Cannot establish TLS connection between spring-ldap client and apacheds - tls1.2
My client code has successfully tested using LDAP protocol against embedded ApacheDS 1.5.5. In End-To-End testing using Apache DS 2.0.0-M23 I was successfully able to establish a LDAPS connection using OpenLDAP. However, I'm having problems using the Java-based spring-ldap to establish LDAPS connection. My code is based on spring-ldap. Any tips for digging deeper into TLS or LDAPS would really be appreciated.
Versions
Oracle JDK: java version "1.8.0_92" with JCE Unlimited Strength Jurisdiction Policy Files.
Spring-Ldap Version : 2.3.1.RELEASE
Spring Version : 4.3.2.RELEASE
Apache DS Version: 2.0.0-M23 deployed in a Docker Container.
Creation of public certificate and private Keys
Based on : Apache DS - Enable SSL
Export the certificate used on the LDAP Server:
[jlee#iel-jlee-lt1 security]$ keytool -genkey -keyalg "RSA" -dname "cn=tangotelecom.com, ou=dev, o=tangotelecom, c=IE" -alias tangotelecom -keystore tangotelecom.ks -storepass secret -validity 730
Enter key password for <tangotelecom>
(RETURN if same as keystore password):
[jlee#iel-jlee-lt1 security]$ keytool -list -keystore tangotelecom.ks
Enter keystore password:
Keystore type: JKS
Keystore provider: SUN
Your keystore contains 1 entry
tangotelecom, 06-Jul-2017, PrivateKeyEntry,
Certificate fingerprint (SHA1): 56:0C:5C:7A:DD:97:F1:4D:A2:B6:D1:2B:EC:D0:11:4A:B1:79:F3:CF
[jlee#iel-jlee-lt1 security]$ keytool -export -keystore tangotelecom.ks -alias tangotelecom -file tangotelecom.cer
Enter keystore password:
Certificate stored in file <tangotelecom.cer>
Import the public certificate into the cacerts file to be used by clients:
[tango#iel-dev-tfsr-vm2 16:30:57 john]$ sudo keytool -import -trustcacerts -keystore /opt/java8/jre/lib/security/cacerts -storepass changeit -noprompt -alias tangotelecom -file /home/tango/john/tangotelecom.cer
[sudo] password for tango:
Certificate was added to keystore
TLS DEBUG
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
%% No cached client session
*** ClientHello, TLSv1.2
RandomCookie: GMT: 1500415942 bytes = { 188, 130, 166, 249, 170, 224, 174, 199, 55, 88, 195, 144, 45, 147, 143, 225, 45, 223, 30, 91, 195, 43, 83, 241, 197, 150, 41, 54 }
Session ID: {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods: { 0 }
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA224withECDSA, SHA224withRSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA
Extension server_name, server_name: [type=host_name (0), value=tangotelecom.com]
***
Thread-8, WRITE: TLSv1.2 Handshake, length = 260
Thread-8, READ: TLSv1.2 Handshake, length = 1257
*** ServerHello, TLSv1.2
RandomCookie: GMT: 1500416088 bytes = { 2, 142, 226, 16, 107, 183, 43, 206, 220, 107, 239, 113, 204, 172, 241, 154, 87, 185, 49, 94, 163, 9, 187, 229, 53, 41, 78, 254 }
Session ID: {89, 111, 136, 88, 183, 123, 76, 181, 211, 21, 149, 160, 218, 222, 226, 244, 139, 145, 143, 72, 3, 7, 184, 96, 34, 155, 76, 54, 60, 117, 215, 179}
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Compression Method: 0
Extension renegotiation_info, renegotiated_connection: <empty>
***
%% Initialized: [Session-1, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384]
** TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
*** Certificate chain
chain [0] = [
[
Version: V3
Subject: CN=tangotelecom.com, OU=dev, O=tangotelecom, C=IE
Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11
Key: Sun RSA public key, 2048 bits
modulus: 22980180191390060691645191877521292031505114546367033225089259442617005098274762521554359946742065878415849288262185146512594592923140681158742168163906077539516435863146152603064701157961527256158756559349035940810739650464273192076580461817700601005238106947505955687153311906740088488389957201959449147054853786865353874624664733186248186940444317144962411956375681259742751499094173934719877768378414836567412356975874572170519318320962628133692056724599530776533547533308568698574604059550372476889963449850184432248569481738632894450321061794712987632959422197533269207285625710288277728878653909213375498707927
public exponent: 65537
Validity: [From: Thu Jul 06 15:48:29 IST 2017,
To: Sat Jul 06 15:48:29 IST 2019]
Issuer: CN=tangotelecom.com, OU=dev, O=tangotelecom, C=IE
SerialNumber: [ 6dce9c09]
Certificate Extensions: 1
[1]: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: E1 BA 73 DD F2 41 0F CF BD 4B 9B 99 D7 01 BD 2F ..s..A...K...../
0010: 7D 9A 31 B7 ..1.
]
]
]
Algorithm: [SHA256withRSA]
Signature:
0000: 2C DB 4A FA BD A9 1D 29 C0 0A 8F 69 7F 39 11 DA ,.J....)...i.9..
0010: 4A 21 0D 66 53 A5 03 CC 33 AB 4D E6 C1 55 75 E3 J!.fS...3.M..Uu.
0020: 8C 22 C6 F9 05 26 27 EF BC C0 CB D8 12 3C 7C 95 ."...&'......<..
0030: 9B 56 88 06 71 CA 3A 17 99 6A 23 53 E9 CC 9B 05 .V..q.:..j#S....
0040: E6 85 89 25 DC CF 95 3A 41 62 5D 0C CE E9 0F D4 ...%...:Ab].....
0050: 7E 0E B6 4D CE 5A 49 F4 BB DD 9A 85 55 C1 39 0E ...M.ZI.....U.9.
0060: 0F B4 34 44 05 64 E5 F3 F0 4A 5C 40 91 2C 1E B3 ..4D.d...J\#.,..
0070: 39 D1 56 71 C2 83 48 CA 31 E5 44 60 B4 65 8D BA 9.Vq..H.1.D`.e..
0080: 70 65 7C 93 B8 84 E4 60 38 EA C7 21 7D AF 30 BD pe.....`8..!..0.
0090: 6F D5 CC 04 DA 33 E8 14 DA E8 AC BA 6A 03 5E C9 o....3......j.^.
00A0: 56 DC 78 07 FB 44 DB A8 B2 4D CE 30 CB 56 7E 6B V.x..D...M.0.V.k
00B0: F6 CE BF 3D B4 77 21 33 53 BA D8 E2 B1 B9 F4 95 ...=.w!3S.......
00C0: 05 7E FB B4 3A CF 09 29 10 B1 4E CF 38 AF 81 D6 ....:..)..N.8...
00D0: 6B DD 60 51 1C 04 27 41 71 98 07 DE B9 82 4A 1A k.`Q..'Aq.....J.
00E0: 0D F7 04 6D 09 F4 E7 1F FE 2C 07 41 EE 84 F3 F6 ...m.....,.A....
00F0: 1A F4 62 87 3D 94 A6 5D FD 3D 8B EE 1B A1 5B 52 ..b.=..].=....[R
]
***
Found trusted certificate:
[
[
Version: V3
Subject: CN=tangotelecom.com, OU=dev, O=tangotelecom, C=IE
Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11
Key: Sun RSA public key, 2048 bits
modulus: 22980180191390060691645191877521292031505114546367033225089259442617005098274762521554359946742065878415849288262185146512594592923140681158742168163906077539516435863146152603064701157961527256158756559349035940810739650464273192076580461817700601005238106947505955687153311906740088488389957201959449147054853786865353874624664733186248186940444317144962411956375681259742751499094173934719877768378414836567412356975874572170519318320962628133692056724599530776533547533308568698574604059550372476889963449850184432248569481738632894450321061794712987632959422197533269207285625710288277728878653909213375498707927
public exponent: 65537
Validity: [From: Thu Jul 06 15:48:29 IST 2017,
To: Sat Jul 06 15:48:29 IST 2019]
Issuer: CN=tangotelecom.com, OU=dev, O=tangotelecom, C=IE
SerialNumber: [ 6dce9c09]
Certificate Extensions: 1
[1]: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: E1 BA 73 DD F2 41 0F CF BD 4B 9B 99 D7 01 BD 2F ..s..A...K...../
0010: 7D 9A 31 B7 ..1.
]
]
]
Algorithm: [SHA256withRSA]
Signature:
0000: 2C DB 4A FA BD A9 1D 29 C0 0A 8F 69 7F 39 11 DA ,.J....)...i.9..
0010: 4A 21 0D 66 53 A5 03 CC 33 AB 4D E6 C1 55 75 E3 J!.fS...3.M..Uu.
0020: 8C 22 C6 F9 05 26 27 EF BC C0 CB D8 12 3C 7C 95 ."...&'......<..
0030: 9B 56 88 06 71 CA 3A 17 99 6A 23 53 E9 CC 9B 05 .V..q.:..j#S....
0040: E6 85 89 25 DC CF 95 3A 41 62 5D 0C CE E9 0F D4 ...%...:Ab].....
0050: 7E 0E B6 4D CE 5A 49 F4 BB DD 9A 85 55 C1 39 0E ...M.ZI.....U.9.
0060: 0F B4 34 44 05 64 E5 F3 F0 4A 5C 40 91 2C 1E B3 ..4D.d...J\#.,..
0070: 39 D1 56 71 C2 83 48 CA 31 E5 44 60 B4 65 8D BA 9.Vq..H.1.D`.e..
0080: 70 65 7C 93 B8 84 E4 60 38 EA C7 21 7D AF 30 BD pe.....`8..!..0.
0090: 6F D5 CC 04 DA 33 E8 14 DA E8 AC BA 6A 03 5E C9 o....3......j.^.
00A0: 56 DC 78 07 FB 44 DB A8 B2 4D CE 30 CB 56 7E 6B V.x..D...M.0.V.k
00B0: F6 CE BF 3D B4 77 21 33 53 BA D8 E2 B1 B9 F4 95 ...=.w!3S.......
00C0: 05 7E FB B4 3A CF 09 29 10 B1 4E CF 38 AF 81 D6 ....:..)..N.8...
00D0: 6B DD 60 51 1C 04 27 41 71 98 07 DE B9 82 4A 1A k.`Q..'Aq.....J.
00E0: 0D F7 04 6D 09 F4 E7 1F FE 2C 07 41 EE 84 F3 F6 ...m.....,.A....
00F0: 1A F4 62 87 3D 94 A6 5D FD 3D 8B EE 1B A1 5B 52 ..b.=..].=....[R
]
*** ECDH ServerKeyExchange
Signature Algorithm SHA512withRSA
Server key: Sun EC public key, 256 bits
public x coord: 65335040139868512120179408985992060136049248034231183953393366519969264579494
public y coord: 99476183036375747385598841109418769282434814800382623908755157948061455956677
parameters: secp256r1 [NIST P-256, X9.62 prime256v1] (1.2.840.10045.3.1.7)
*** ServerHelloDone
*** ECDHClientKeyExchange
ECDH Public value: { 4, 6, 89, 131, 180, 42, 189, 111, 119, 56, 149, 20, 50, 182, 23, 83, 192, 173, 201, 60, 5, 132, 156, 221, 3, 44, 131, 63, 1, 166, 164, 34, 3, 56, 203, 122, 234, 174, 144, 123, 135, 210, 236, 219, 230, 153, 161, 126, 189, 78, 72, 8, 98, 201, 57, 28, 243, 18, 56, 113, 156, 118, 238, 160, 238 }
Thread-8, WRITE: TLSv1.2 Handshake, length = 70
SESSION KEYGEN:
PreMaster Secret:
0000: BD 2B CF E4 3E 6A 0D 32 97 16 67 3E 5A 46 CD CD .+..>j.2..g>ZF..
0010: CA 52 5B 89 28 43 45 35 09 89 74 1F B6 D9 02 7B .R[.(CE5..t.....
CONNECTION KEYGEN:
Client Nonce:
0000: 59 6F 88 C6 BC 82 A6 F9 AA E0 AE C7 37 58 C3 90 Yo..........7X..
0010: 2D 93 8F E1 2D DF 1E 5B C3 2B 53 F1 C5 96 29 36 -...-..[.+S...)6
Server Nonce:
0000: 59 6F 88 58 02 8E E2 10 6B B7 2B CE DC 6B EF 71 Yo.X....k.+..k.q
0010: CC AC F1 9A 57 B9 31 5E A3 09 BB E5 35 29 4E FE ....W.1^....5)N.
Master Secret:
0000: 44 0B B5 4E 2C 69 E1 68 85 F3 21 08 1A 75 F8 01 D..N,i.h..!..u..
0010: 33 1A 6B 3A 55 7B D3 65 F8 D6 3C BD 10 40 B2 E4 3.k:U..e..<..#..
0020: A2 BC 8A 31 1F 41 9E C6 FC A4 40 F7 2F B2 59 3F ...1.A....#./.Y?
Client MAC write Secret:
0000: C0 97 F8 99 19 72 9D 18 63 FD CD 8C 64 23 BC B1 .....r..c...d#..
0010: 7B 58 D4 52 9C 71 E6 42 0A 20 ED 53 31 5F 27 A7 .X.R.q.B. .S1_'.
0020: 47 3E EA 1D AA 12 CA AA 14 1B 63 98 E0 1B AD F8 G>........c.....
Server MAC write Secret:
0000: 98 BE 74 96 5D 1B 69 7D 96 0D 83 25 C3 D6 24 B0 ..t.].i....%..$.
0010: 57 15 08 62 A6 69 E3 DA 77 3D 73 A3 E6 D9 A8 7A W..b.i..w=s....z
0020: 46 E0 D2 49 ED 53 86 45 18 97 92 C3 C9 61 45 4E F..I.S.E.....aEN
Client write key:
0000: 27 67 0E 91 81 3A 6A 5B 87 78 1D E0 EB 6B C7 AE 'g...:j[.x...k..
0010: B8 78 13 9F 6F C2 8B 4E AC 3F 01 07 BC 5C 9B 0E .x..o..N.?...\..
Server write key:
0000: 3E D2 EE 99 D4 53 84 15 C6 D6 66 5D A8 A5 40 7C >....S....f]..#.
0010: 65 BB 8E A8 DF F7 B8 22 6C EF 6C 82 26 63 7D 99 e......"l.l.&c..
... no IV derived for this protocol
Thread-8, WRITE: TLSv1.2 Change Cipher Spec, length = 1
*** Finished
verify_data: { 101, 250, 185, 66, 42, 146, 49, 129, 108, 63, 34, 156 }
***
Thread-8, WRITE: TLSv1.2 Handshake, length = 96
Thread-8, READ: TLSv1.2 Change Cipher Spec, length = 1
Thread-8, READ: TLSv1.2 Handshake, length = 96
*** Finished
verify_data: { 221, 251, 110, 51, 35, 95, 63, 112, 169, 189, 61, 120 }
***
%% Cached client session: [Session-1, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384]
ForkJoinPool.commonPool-worker-2, WRITE: TLSv1.2 Application Data, length = 96
Thread-8, handling exception: javax.net.ssl.SSLException: Unsupported record version Unknown-38.2
%% Invalidated: [Session-1, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384]
Thread-8, SEND TLSv1.2 ALERT: fatal, description = unexpected_message
Thread-8, WRITE: TLSv1.2 Alert, length = 80
Thread-8, called closeSocket()
Thread-8, called close()
Thread-8, called closeInternal(true)
Spring LDAP Client Configuration
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:ldap="http://www.springframework.org/schema/ldap"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/ldap http://www.springframework.org/schema/ldap/spring-ldap.xsd">
<context:property-placeholder location="classpath:application.properties"/>
<bean id="ldapAuthenticationStrategy" class="org.springframework.ldap.core.support.DefaultTlsDirContextAuthenticationStrategy">
<property name="shutdownTlsGracefully" value="true"/>
</bean>
<ldap:context-source url="${ldap.primary.url}, ${ldap.secondary.url}"
username="${ldap.userDn}"
password="${ldap.password}"
base="${ldap.base}"
referral="follow"
native-pooling="false"
authentication-strategy-ref="ldapAuthenticationStrategy">
</ldap:context-source>
<ldap:ldap-template id="ldapTemplate" context-source-ref="contextSource" time-limit="5000"/>
</beans>
Code
public class TangoLdapClient {
static final String UID = "uid";
private final LdapTemplate ldapTemplate;
/**
* Constructor.
* #param ldapTemplate {#link LdapTemplate}.
*/
public TangoLdapClient(#NonNull final LdapTemplate ldapTemplate) {
this.ldapTemplate = ldapTemplate;
}
/**
* Authenticate with username and password.
* #param username username.
* #param password password.
* #throws EmptyResultDataAccessException in the case that the username is not found, and therefore cannot be mapped to dn.
* #throws AuthenticationException in the case where the password doesn't match.
*/
public void authenticate(#NonNull final String username, #NonNull final String password)
throws EmptyResultDataAccessException, AuthenticationException {
Preconditions.checkArgument(StringUtils.isNotBlank(username));
ldapTemplate.authenticate(buildFindUserFromUserName(username), password,
(ctx, ldapEntryIdentification) -> wrappedMapper(ctx, ldapEntryIdentification));
}
private LdapQuery buildFindUserFromUserName(final String username) {
return query().where(UID).is(username);
}
private static DirContextOperations wrappedMapper(final DirContext ctx,
final LdapEntryIdentification ldapEntryIdentification) {
try {
return (DirContextOperations) ctx.lookup(ldapEntryIdentification.getRelativeName());
} catch (NamingException e) {
throw new RuntimeException("Failed to lookup " + ldapEntryIdentification.getRelativeName(), e);
}
}
}
Related
TLS version on Http trace
I'm trying to understang which TLS version is used based on this logs (http trace) System.Net Information: 0 : [2544] SecureChannel#49129953::.AcquireClientCredentials, new SecureCredential() (flags=(ValidateManual, NoDefaultCred, SendAuxRecord), m_ProtocolFlags=(Ssl3Client, Tls10Client), m_EncryptionPolicy=RequireEncryption) Algorithm: RSA Length: 2048 Key Blob: 30 82 01 0a 02 82 01 01 00 b8 de 6a 2c a0 05 1d c1 2e 54 2d de 74 40 a6 83 2b 81 25 29 8d c1 2b e1 4d 4b 63 bd 7f c0 75 fe 15 eb 6b a6 2f 3c 65 d6 7a 55 dc 68 07 1c 6c 2e 8c cd d5 01 74 9f ca ca bb 5e b0 6d 9a 44 d1 1c 74 11 ca 4f 44 fa 59 59 22 f5 f9 c2 00 21 d6 1d a3 09 5a 0e fe da b7 ea d2 c8 55 51 c7 53 90 d1 b9 bf 2c 98 49 75 82 30 .... System.Net Information: 0 : [2544] SecureChannel#49129953 - Remote certificate was verified as valid by the user. System.Net Information: 0 : [2544] ProcessAuthentication(Protocol=Tls, Cipher=Aes128 128 bit strength, Hash=Sha1 160 bit strength, Key Exchange=RsaKeyX 2048 bit strength). Any idea? If you need more log let me know. Thank you
... m_ProtocolFlags=(Ssl3Client, Tls10Client) ... ProcessAuthentication(Protocol=Tls Based on this it should be TLS 1.0. For other versions like TLS 1.2 there is probably something like Protocol=Tls12 instead
How and When the Handshake Protocol to use to the Certificate private key?
How does the server using the Certificate Private Key to create Certificate Verify message in TLS 1.3? And how the Client using the Certificate public key to verify the handshake not to be modify? Just in TLS 1.3 not TLS 1.2
As a good overview of the phases of the TLS 1.3 handshake I like to use this site, which breaks down the connection to easier to understand phases then going through the RFC's. From the above site: Signature Because the server is generating ephemeral keys for each session (optional in TLS 1.2, mandatory in TLS 1.3) the session is not inherently tied to the certificate as it was in previous versions of TLS, when the certificate's public/private key were used for key exchange. To prove that the server owns the server certificate (giving the certificate validity in this TLS session), it signs a hash of the handshake messages using the certificate's private key. The signature can be proven valid by the client by using the certificate's public key. 08 04 - reserved value for RSA-PSS-RSAE-SHA256 signature 01 00 - 0x100 (256) bytes of signature data follows 17 fe b5 ... 36 9f 9e - a signature over this handshake's hash We can verify the signature ourselves using the server's certificate at the command line: build the data that was signed: 1. add 64 space characters $ echo -n ' ' > /tmp/tosign $ echo -n ' ' >> /tmp/tosign 2. add this fixed string $ echo -n 'TLS 1.3, server CertificateVerify' >> /tmp/tosign 3. add a single null character $ echo -en '\0' >> /tmp/tosign 4. add hash of handshake to this point $ handshake_hash=3e66361ada42c7cb97f9a62b00cae1d8b584174c745f9a338cf9f7cdd51d15f8 $ echo $handshake_hash | xxd -r -p >> /tmp/tosign copy the signature that we want to verify $ echo "17 fe b5 33 ca 6d 00 7d 00 58 25 79 68 42 4b bc 3a a6 90 9e 9d 49 55 75 76 a5 20 e0 4a 5e f0 5f 0e 86 d2 4f f4 3f 8e b8 61 ee f5 95 22 8d 70 32 aa 36 0f 71 4e 66 74 13 92 6e f4 f8 b5 80 3b 69 e3 55 19 e3 b2 3f 43 73 df ac 67 87 06 6d cb 47 56 b5 45 60 e0 88 6e 9b 96 2c 4a d2 8d ab 26 ba d1 ab c2 59 16 b0 9a f2 86 53 7f 68 4f 80 8a ef ee 73 04 6c b7 df 0a 84 fb b5 96 7a ca 13 1f 4b 1c f3 89 79 94 03 a3 0c 02 d2 9c bd ad b7 25 12 db 9c ec 2e 5e 1d 00 e5 0c af cf 6f 21 09 1e bc 4f 25 3c 5e ab 01 a6 79 ba ea be ed b9 c9 61 8f 66 00 6b 82 44 d6 62 2a aa 56 88 7c cf c6 6a 0f 38 51 df a1 3a 78 cf f7 99 1e 03 cb 2c 3a 0e d8 7d 73 67 36 2e b7 80 5b 00 b2 52 4f f2 98 a4 da 48 7c ac de af 8a 23 36 c5 63 1b 3e fa 93 5b b4 11 e7 53 ca 13 b0 15 fe c7 e4 a7 30 f1 36 9f 9e" | xxd -r -p > /tmp/sig extract the public key from the certificate $ openssl x509 -pubkey -noout -in server.crt > server.pub verify the signature $ cat /tmp/tosign | openssl dgst -verify server.pub -sha256 \ -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 -signature /tmp/sig Verified OK
RSA public key, PEM_write_RSAPublicKey, and rsautl compatibility [duplicate]
I've generated a public key using openssl BIGNUM* e = BN_new(); BN_set_word(e, 17); RSA* rsa = RSA_new(); if(!RSA_generate_key_ex(rsa, 2048, e, NULL)) { LOG(security, debug) << "failed to generate private key"; } And these are written to files: FILE* pubwriter = fopen("key.pub", "wb"); int err = PEM_write_RSAPublicKey(pubwriter, key); if(!err) { throw new std::runtime_error("Failed to store public key"); } FILE* privwriter = fopen("key.priv", "wb"); std::string password = "password"; err = PEM_write_RSAPrivateKey(privwriter, key, EVP_des_ede3_cbc(), (unsigned char*)password.c_str(), password.size(), NULL, NULL); And they seem to be stored correctly, key.pub then contains something like -----BEGIN RSA PUBLIC KEY----- MIIBCAKCAQEA0rG1b0g3NIsDT8HkzgTx8BUI9LhueWbH1NuAvIh9qTF57GzEXuTu jxBcuSzWXlR83ci4oITp7VqV6KLVoJryf8orGXBVi9A73JYOQVB6FEzARKym/g8E fSEwSmdQ4NfiTESwOCtIextdu3x8pANSYDyyqdiWsSHy0SiZmkbvdVYomIBJZOV9 jhb3mkmD0WUYie9AXziTbli97YqDiN168kMI+7ePpbNJFSVSIUkPPocSgvgcAux/ HuDqftzBgyAF3NGb3AAra1A8T7yPOqLyYyXdIJmF+/Svk5PdMbZVE/U76cjBThch Q9AiLo25hOjkmtuEQubCuwrUDleblr93aQIBEQ== -----END RSA PUBLIC KEY----- Now I want to try these to make sure I haven't got anything wrong but it wont' load: $ openssl rsautl -encrypt -inkey key.pub -pubin -in data.txt -out enc.txt unable to load Public Key What am I missing?
int err = PEM_write_RSAPublicKey(pubwriter, key); PEM_write_RSAPublicKey writes just the public key. You can make the command work using PEM_write_PUBKEY. The various *_PUBKEY routines write the SubjectPublicKeyInfo, which includes the algorithm OID and public key. When you write the SubjectPublicKeyInfo, OpenSSL calls it "traditional" format. It will also have the header -----BEGIN PUBLIC KEY----- (and not -----BEGIN RSA PUBLIC KEY-----). Below, I used PEM_write_PUBKEY to save the public key rsa-public.pem: $ openssl rsautl -encrypt -inkey rsa-public.pem -pubin -in data.txt -out enc.bin $ hexdump enc.bin 0000000 45 53 31 ad 9d 6a c4 37 1e 22 4b 83 c6 27 c8 3c 0000010 df cb 87 a4 60 d8 63 9a 83 9f ee ca e5 8f 8e dd 0000020 d4 d0 98 97 1c b3 36 55 f1 84 ea 7f fe bf 22 b6 0000030 93 20 a2 d5 b2 bd 20 cc 52 8e c7 1b 33 e6 40 40 0000040 cb 7d 6f 17 f1 eb f1 d4 9d 66 fb 67 eb 67 ba 2a 0000050 44 c2 52 15 54 8d 79 76 ad 26 61 35 27 9c bb 6c 0000060 5b 0e 79 b3 d3 27 0b a9 72 17 0d 2d 19 d7 60 19 0000070 16 46 80 4b c0 ae 75 53 9e 6f f5 24 d9 1a a3 6a 0000080 2f 38 13 f6 72 19 20 94 de 40 75 20 51 f4 08 f4 0000090 74 b8 ac 49 01 d6 f8 f4 e5 79 38 88 2d 02 b7 bd 00000a0 f7 63 c1 e1 e5 ec 39 a1 fa 7c ce 0f 83 16 70 7e 00000b0 cd 7e f5 6b 51 c2 db d7 f6 c4 46 5d e5 93 d3 3d 00000c0 ab e6 3b 1a 97 d4 c9 54 e7 aa 90 2d 0a b9 c2 4b 00000d0 3c 58 fd 26 58 5a 63 c0 8c ae b9 72 24 a1 68 5d 00000e0 83 d7 5b ae 56 2a 78 46 8c f4 21 96 bd d3 0c 93 00000f0 8e 35 61 9c b8 56 2e 3a 4e 05 d9 1e 0b 59 14 11 0000100 PEM_write_PUBKEY requires a EVP_PKEY. Just use something like: EVP_PKEY* pkey = EVP_PKEY_new(); ASSERT(pkey != NULL); int rc = EVP_PKEY_set1_RSA(pkey, rsa); ASSERT(rc == 1); ... EVP_PKEY_free(pkey); The set1 bumps the reference count on the RSA key, so you have to free it through EVP_PKEY_free. The difference between PEM_write_RSAPublicKey and PEM_write_PUBKEY is very obvious when you save in ASN.1/DER. But it gets lost in the PEM encoding. Here's the non-traditional key in ASN.1/DER and dumped. Its the ASN.1 equivalent of PEM_write_RSAPublicKey. Its just {n,e}: $ dumpasn1 rsa-public-1.der 0 266: SEQUENCE { 4 257: INTEGER : 00 D1 C8 05 BF AC 04 72 AA 0E 84 FB 47 75 59 97 : E1 81 65 0B 0A 1D 9D 2A A8 A1 E0 B1 14 5D 57 69 : D4 D2 E2 C6 64 54 94 C2 92 CC C7 99 1A 97 89 72 : F6 36 6A A7 B8 34 2C AB A9 CB 77 EB 0D A1 4E 72 : 24 9F 96 D6 1C 28 ED 44 E8 0B 22 7F F3 5B 52 E2 : 7E A6 5E F1 7C A2 29 4F F1 8B 9D 0F 94 27 05 D5 : BD 2E 1A AD B4 12 0D E0 69 3E 0B 1B A7 F8 71 B5 : AD 22 4B 18 FF 72 88 F3 C5 77 B0 CF 88 5C F4 19 : [ Another 129 bytes skipped ] 265 3: INTEGER 65537 : } 0 warnings, 0 errors. Here's the traditional public key in ASN.1/DER and dumped. Its the ASN.1 equivalent of PEM_write_PUBKEY. Its the one that writes the SubjectPublicKeyInfo, and it includes an algorithm OID and public key: $ dumpasn1 rsa-public-2.der 0 290: SEQUENCE { 4 13: SEQUENCE { 6 9: OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1) 17 0: NULL : } 19 271: BIT STRING, encapsulates { 24 266: SEQUENCE { 28 257: INTEGER : 00 D1 C8 05 BF AC 04 72 AA 0E 84 FB 47 75 59 97 : E1 81 65 0B 0A 1D 9D 2A A8 A1 E0 B1 14 5D 57 69 : D4 D2 E2 C6 64 54 94 C2 92 CC C7 99 1A 97 89 72 : F6 36 6A A7 B8 34 2C AB A9 CB 77 EB 0D A1 4E 72 : 24 9F 96 D6 1C 28 ED 44 E8 0B 22 7F F3 5B 52 E2 : 7E A6 5E F1 7C A2 29 4F F1 8B 9D 0F 94 27 05 D5 : BD 2E 1A AD B4 12 0D E0 69 3E 0B 1B A7 F8 71 B5 : AD 22 4B 18 FF 72 88 F3 C5 77 B0 CF 88 5C F4 19 : [ Another 129 bytes skipped ] 289 3: INTEGER 65537 : } : } : } 0 warnings, 0 errors. err = PEM_write_RSAPrivateKey(privwriter, key, EVP_des_ede3_cbc(), (unsigned char*)password.c_str(), password.size(), NULL, NULL); I believe the OpenSSL folks recommend you use PEM_write_PKCS8PrivateKey. See PEM(3) and pkcs8(1). Now I want to try these to make sure I haven't got anything wrong but it wont' load: $ openssl rsautl -encrypt -inkey key.pub -pubin -in data.txt -out enc.txt You can understand the behavior by looking at <openssl src>/apps/rsautl.c. Here are the relevant lines: else if (!strcmp(*argv, "-pubin")) { key_type = KEY_PUBKEY; } ... case KEY_PUBKEY: pkey = load_pubkey(bio_err, keyfile, keyform, 0, NULL, e, "Public Key"); break; ... Then, in apps.c: if (format == FORMAT_ASN1) { pkey = d2i_PUBKEY_bio(key, NULL); } ... else if (format == FORMAT_PEM) { pkey = PEM_read_bio_PUBKEY(key, NULL, ...); } ... The observation above is the routines are using *_PUBKEY. There's also a code path based on format == FORMAT_PEMRSA that calls PEM_read_bio_RSAPublicKey, but I don't know how to trigger it. Looking at rsautl(1), I don't think you can because there's no switch that exposes it. If it was going to trigger, it would be based on a combination of the -keyform option combined with format == FORMAT_PEMRSA. But apps.c's str2fmt does not return a FORMAT_PEMRSA. I think that means your only option is to use a SubjectPublicKeyInfo. And that means using PEM_write_PUBKEY (or convert the key after the fact). Now related: OpenSSL Bug Report, Issue 3887: rsautl and intelligent retry for Public Key parse after Traditional/Subject Public Key Info parse fails.
I faced the same problem and managed to debug by following #jww answer above. In the process I discover a simple command that does not require a EVP_PKEY. Just use PEM_write_bio_RSA_PUBKEY(BIO * bp, RSA * x) directly. Read PEM_write documentation for details.
RSA Public Key format
Where can i find some documentation on the format of an RSA public key? An RSA public key formatted by OpenSSH: ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQB/nAmOjTmezNUDKYvEeIRf2YnwM9/uUG1d0BYsc8/tRtx+RGi7N2lUbp728MXGwdnL9od4cItzky/zVdLZE2cycOa18xBK9cOWmcKS0A8FYBxEQWJ/q9YVUgZbFKfYGaGQxsER+A0w/fX8ALuk78ktP31K69LcQgxIsl7rNzxsoOQKJ/CIxOGMMxczYTiEoLvQhapFQMs3FL96didKr/QbrfB1WT6s3838SEaXfgZvLef1YB2xmfhbT9OXFE3FXvh2UPBfN+ffE7iiayQf/2XR+8j4N4bW30DiPtOQLGUrH1y5X/rpNZNlWW2+jGIxqZtgWg7lTy3mXy5x836Sj/6L The same public key formatted for use in Secure Shell (RFC 4716 - The Secure Shell (SSH) Public Key File Format): ---- BEGIN SSH2 PUBLIC KEY ---- AAAAB3NzaC1yc2EAAAABJQAAAQB/nAmOjTmezNUDKYvEeIRf2YnwM9/uUG1d0BYs c8/tRtx+RGi7N2lUbp728MXGwdnL9od4cItzky/zVdLZE2cycOa18xBK9cOWmcKS 0A8FYBxEQWJ/q9YVUgZbFKfYGaGQxsER+A0w/fX8ALuk78ktP31K69LcQgxIsl7r NzxsoOQKJ/CIxOGMMxczYTiEoLvQhapFQMs3FL96didKr/QbrfB1WT6s3838SEaX fgZvLef1YB2xmfhbT9OXFE3FXvh2UPBfN+ffE7iiayQf/2XR+8j4N4bW30DiPtOQ LGUrH1y5X/rpNZNlWW2+jGIxqZtgWg7lTy3mXy5x836Sj/6L ---- END SSH2 PUBLIC KEY ---- The same public key formatted as an RSA public key (note the five -, and no space): -----BEGIN RSA PUBLIC KEY----- MIIBCgKCAQEA+xGZ/wcz9ugFpP07Nspo6U17l0YhFiFpxxU4pTk3Lifz9R3zsIsu ERwta7+fWIfxOo208ett/jhskiVodSEt3QBGh4XBipyWopKwZ93HHaDVZAALi/2A +xTBtWdEo7XGUujKDvC2/aZKukfjpOiUI8AhLAfjmlcD/UZ1QPh0mHsglRNCmpCw mwSXA9VNmhz+PiB+Dml4WWnKW/VHo2ujTXxq7+efMU4H2fny3Se3KYOsFPFGZ1TN QSYlFuShWrHPtiLmUdPoP6CV2mML1tk+l7DIIqXrQhLUKDACeM5roMx0kLhUWB8P +0uj1CNlNN4JRZlC7xFfqiMbFRU9Z4N6YwIDAQAB -----END RSA PUBLIC KEY----- The hex dump of the base-64 encoded data: 00 00 00 07 73 73 68 2d 72 73 61 00 00 00 01 25 00 00 01 00 7f 9c 09 8e 8d 39 9e cc d5 03 29 8b c4 78 84 5f d9 89 f0 33 df ee 50 6d 5d d0 16 2c 73 cf ed 46 dc 7e 44 68 bb 37 69 54 6e 9e f6 f0 c5 c6 c1 d9 cb f6 87 78 70 8b 73 93 2f f3 55 d2 d9 13 67 32 70 e6 b5 f3 10 4a f5 c3 96 99 c2 92 d0 0f 05 60 1c 44 41 62 7f ab d6 15 52 06 5b 14 a7 d8 19 a1 90 c6 c1 11 f8 0d 30 fd f5 fc 00 bb a4 ef c9 2d 3f 7d 4a eb d2 dc 42 0c 48 b2 5e eb 37 3c 6c a0 e4 0a 27 f0 88 c4 e1 8c 33 17 33 61 38 84 a0 bb d0 85 aa 45 40 cb 37 14 bf 7a 76 27 4a af f4 1b ad f0 75 59 3e ac df cd fc 48 46 97 7e 06 6f 2d e7 f5 60 1d b1 99 f8 5b 4f d3 97 14 4d c5 5e f8 76 50 f0 5f 37 e7 df 13 b8 a2 6b 24 1f ff 65 d1 fb c8 f8 37 86 d6 df 40 e2 3e d3 90 2c 65 2b 1f 5c b9 5f fa e9 35 93 65 59 6d be 8c 62 31 a9 9b 60 5a 0e e5 4f 2d e6 5f 2e 71 f3 7e 92 8f fe 8b i've read that there are a couple of formats🕗: Key data may be encoded in three general ways: Binary DER-encoded format. This is sometimes called ASN.1 BER-encoded PEM or base64 format. This is the same data as the DER-encoded file but it is encoded in base64 with additional header and footer lines XML format. If it's ASN.1, the hex certainly doesn't look like it. What's the format of an RSA public key? See also RSA Key Formats Abstract Syntax Notation One Convert Base64 Public Key to XML Signature 🕗 Decode PEM formats
You can't just change the delimiters from ---- BEGIN SSH2 PUBLIC KEY ---- to -----BEGIN RSA PUBLIC KEY----- and expect that it will be sufficient to convert from one format to another (which is what you've done in your example). This article has a good explanation about both formats. What you get in an RSA PUBLIC KEY is closer to the content of a PUBLIC KEY, but you need to offset the start of your ASN.1 structure to reflect the fact that PUBLIC KEY also has an indicator saying which type of key it is (see RFC 3447). You can see this using openssl asn1parse and -strparse 19, as described in this answer. EDIT: Following your edit, your can get the details of your RSA PUBLIC KEY structure using grep -v -- ----- | tr -d '\n' | base64 -d | openssl asn1parse -inform DER: 0:d=0 hl=4 l= 266 cons: SEQUENCE 4:d=1 hl=4 l= 257 prim: INTEGER :FB1199FF0733F6E805A4FD3B36CA68E94D7B974621162169C71538A539372E27F3F51DF3B08B2E111C2D6BBF9F5887F13A8DB4F1EB6DFE386C92256875212DDD00468785C18A9C96A292B067DDC71DA0D564000B8BFD80FB14C1B56744A3B5C652E8CA0EF0B6FDA64ABA47E3A4E89423C0212C07E39A5703FD467540F874987B209513429A90B09B049703D54D9A1CFE3E207E0E69785969CA5BF547A36BA34D7C6AEFE79F314E07D9F9F2DD27B72983AC14F1466754CD41262516E4A15AB1CFB622E651D3E83FA095DA630BD6D93E97B0C822A5EB4212D428300278CE6BA0CC7490B854581F0FFB4BA3D4236534DE09459942EF115FAA231B15153D67837A63 265:d=1 hl=2 l= 3 prim: INTEGER :010001 To decode the SSH key format, you need to use the data format specification in RFC 4251 too, in conjunction with RFC 4253: The "ssh-rsa" key format has the following specific encoding: string "ssh-rsa" mpint e mpint n For example, at the beginning, you get 00 00 00 07 73 73 68 2d 72 73 61. The first four bytes (00 00 00 07) give you the length. The rest is the string itself: 73=s, 68=h, ... -> 73 73 68 2d 72 73 61=ssh-rsa, followed by the exponent of length 1 (00 00 00 01 25) and the modulus of length 256 (00 00 01 00 7f ...).
Starting from the decoded base64 data of an OpenSSL rsa-ssh Key, i've been able to guess a format: 00 00 00 07: four byte length prefix (7 bytes) 73 73 68 2d 72 73 61: "ssh-rsa" 00 00 00 01: four byte length prefix (1 byte) 25: RSA Exponent (e): 25 00 00 01 00: four byte length prefix (256 bytes) RSA Modulus (n): 7f 9c 09 8e 8d 39 9e cc d5 03 29 8b c4 78 84 5f d9 89 f0 33 df ee 50 6d 5d d0 16 2c 73 cf ed 46 dc 7e 44 68 bb 37 69 54 6e 9e f6 f0 c5 c6 c1 d9 cb f6 87 78 70 8b 73 93 2f f3 55 d2 d9 13 67 32 70 e6 b5 f3 10 4a f5 c3 96 99 c2 92 d0 0f 05 60 1c 44 41 62 7f ab d6 15 52 06 5b 14 a7 d8 19 a1 90 c6 c1 11 f8 0d 30 fd f5 fc 00 bb a4 ef c9 2d 3f 7d 4a eb d2 dc 42 0c 48 b2 5e eb 37 3c 6c a0 e4 0a 27 f0 88 c4 e1 8c 33 17 33 61 38 84 a0 bb d0 85 aa 45 40 cb 37 14 bf 7a 76 27 4a af f4 1b ad f0 75 59 3e ac df cd fc 48 46 97 7e 06 6f 2d e7 f5 60 1d b1 99 f8 5b 4f d3 97 14 4d c5 5e f8 76 50 f0 5f 37 e7 df 13 b8 a2 6b 24 1f ff 65 d1 fb c8 f8 37 86 d6 df 40 e2 3e d3 90 2c 65 2b 1f 5c b9 5f fa e9 35 93 65 59 6d be 8c 62 31 a9 9b 60 5a 0e e5 4f 2d e6 5f 2e 71 f3 7e 92 8f fe 8b The closest validation of my theory i can find it from RFC 4253: The "ssh-rsa" key format has the following specific encoding: string "ssh-rsa" mpint e mpint n Here the 'e' and 'n' parameters form the signature key blob. But it doesn't explain the length prefixes. Taking the random RSA PUBLIC KEY i found (in the question), and decoding the base64 into hex: 30 82 01 0a 02 82 01 01 00 fb 11 99 ff 07 33 f6 e8 05 a4 fd 3b 36 ca 68 e9 4d 7b 97 46 21 16 21 69 c7 15 38 a5 39 37 2e 27 f3 f5 1d f3 b0 8b 2e 11 1c 2d 6b bf 9f 58 87 f1 3a 8d b4 f1 eb 6d fe 38 6c 92 25 68 75 21 2d dd 00 46 87 85 c1 8a 9c 96 a2 92 b0 67 dd c7 1d a0 d5 64 00 0b 8b fd 80 fb 14 c1 b5 67 44 a3 b5 c6 52 e8 ca 0e f0 b6 fd a6 4a ba 47 e3 a4 e8 94 23 c0 21 2c 07 e3 9a 57 03 fd 46 75 40 f8 74 98 7b 20 95 13 42 9a 90 b0 9b 04 97 03 d5 4d 9a 1c fe 3e 20 7e 0e 69 78 59 69 ca 5b f5 47 a3 6b a3 4d 7c 6a ef e7 9f 31 4e 07 d9 f9 f2 dd 27 b7 29 83 ac 14 f1 46 67 54 cd 41 26 25 16 e4 a1 5a b1 cf b6 22 e6 51 d3 e8 3f a0 95 da 63 0b d6 d9 3e 97 b0 c8 22 a5 eb 42 12 d4 28 30 02 78 ce 6b a0 cc 74 90 b8 54 58 1f 0f fb 4b a3 d4 23 65 34 de 09 45 99 42 ef 11 5f aa 23 1b 15 15 3d 67 83 7a 63 02 03 01 00 01 From RFC3447 - Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography Specifications Version 2.1: A.1.1 RSA public key syntax An RSA public key should be represented with the ASN.1 type RSAPublicKey: RSAPublicKey ::= SEQUENCE { modulus INTEGER, -- n publicExponent INTEGER -- e } The fields of type RSAPublicKey have the following meanings: modulus is the RSA modulus n. publicExponent is the RSA public exponent e. Using Microsoft's excellent (and the only real) ASN.1 documentation: 30 82 01 0a ;SEQUENCE (0x010A bytes: 266 bytes) | 02 82 01 01 ;INTEGER (0x0101 bytes: 257 bytes) | | 00 ;leading zero because high-bit, but number is positive | | fb 11 99 ff 07 33 f6 e8 05 a4 fd 3b 36 ca 68 | | e9 4d 7b 97 46 21 16 21 69 c7 15 38 a5 39 37 2e 27 f3 f5 1d f3 b0 8b 2e | | 11 1c 2d 6b bf 9f 58 87 f1 3a 8d b4 f1 eb 6d fe 38 6c 92 25 68 75 21 2d | | dd 00 46 87 85 c1 8a 9c 96 a2 92 b0 67 dd c7 1d a0 d5 64 00 0b 8b fd 80 | | fb 14 c1 b5 67 44 a3 b5 c6 52 e8 ca 0e f0 b6 fd a6 4a ba 47 e3 a4 e8 94 | | 23 c0 21 2c 07 e3 9a 57 03 fd 46 75 40 f8 74 98 7b 20 95 13 42 9a 90 b0 | | 9b 04 97 03 d5 4d 9a 1c fe 3e 20 7e 0e 69 78 59 69 ca 5b f5 47 a3 6b a3 | | 4d 7c 6a ef e7 9f 31 4e 07 d9 f9 f2 dd 27 b7 29 83 ac 14 f1 46 67 54 cd | | 41 26 25 16 e4 a1 5a b1 cf b6 22 e6 51 d3 e8 3f a0 95 da 63 0b d6 d9 3e | | 97 b0 c8 22 a5 eb 42 12 d4 28 30 02 78 ce 6b a0 cc 74 90 b8 54 58 1f 0f | | fb 4b a3 d4 23 65 34 de 09 45 99 42 ef 11 5f aa 23 1b 15 15 3d 67 83 7a | | 63 | 02 03 ;INTEGER (3 bytes) | 01 00 01 giving the public key modulus and exponent: modulus = 0xfb1199ff0733f6e805a4fd3b36ca68...837a63 exponent = 65,537 Update: My expanded form of this answer in another question
Reference Decoder of CRL,CRT,CSR,NEW CSR,PRIVATE KEY, PUBLIC KEY,RSA,RSA Public Key Parser RSA Public Key -----BEGIN RSA PUBLIC KEY----- -----END RSA PUBLIC KEY----- Encrypted Private Key -----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED -----END RSA PRIVATE KEY----- CRL -----BEGIN X509 CRL----- -----END X509 CRL----- CRT -----BEGIN CERTIFICATE----- -----END CERTIFICATE----- CSR -----BEGIN CERTIFICATE REQUEST----- -----END CERTIFICATE REQUEST----- NEW CSR -----BEGIN NEW CERTIFICATE REQUEST----- -----END NEW CERTIFICATE REQUEST----- PEM -----BEGIN RSA PRIVATE KEY----- -----END RSA PRIVATE KEY----- PKCS7 -----BEGIN PKCS7----- -----END PKCS7----- PRIVATE KEY -----BEGIN PRIVATE KEY----- -----END PRIVATE KEY----- DSA KEY -----BEGIN DSA PRIVATE KEY----- -----END DSA PRIVATE KEY----- Elliptic Curve -----BEGIN EC PRIVATE KEY----- -----END EC PRIVATE KEY----- PGP Private Key -----BEGIN PGP PRIVATE KEY BLOCK----- -----END PGP PRIVATE KEY BLOCK----- PGP Public Key -----BEGIN PGP PUBLIC KEY BLOCK----- -----END PGP PUBLIC KEY BLOCK-----
How to see the encrypted key in wireshark, during ssl key exchange?
In wireshark, I am able to see the encrypted data to and fro from my PC. It does not use diffie hellman algorihm for key exchange because I see only the Client Key Exchange packet but there is no Server Key Exchange packet. That means the browser is sending the encrypted key to the server(encrypted using the server's public key). But I do not see any encrypted data in that packet("Client Key Exchange"). How to view the encrypted key?
You won't see the encrypted shared-key, it's not exchanged. You can see the encrypted pre-master secret when using RSA authenticated key exchange. (Note that using Ephemeral Diffie-Hellman isn't the only reason for not seeing a server key exchange message: it could also use a DH_DSS or DH_RSA cipher suite, but this is unusual as far as I know). If you follow the instructions about decrypting SSL with Wireshark, use the "SSL debug file" option to store the logs into a file. (Note that the user interface has changed slightly in newer versions of Wireshark, in the way you configure the private key.) The log files will contain the pre-master secret and the shared keys. (By the way, you need the server's private key to do this, of course.) Using the sample data provided on the Wireshark page, you get: pre master encrypted[128]: 65 51 2d a6 d4 a7 38 df ac 79 1f 0b d9 b2 61 7d 73 88 32 d9 f2 62 3a 8b 11 04 75 ca 42 ff 4e d9 cc b9 fa 86 f3 16 2f 09 73 51 66 aa 29 cd 80 61 0f e8 13 ce 5b 8e 0a 23 f8 91 5e 5f 54 70 80 8e 7b 28 ef b6 69 b2 59 85 74 98 e2 7e d8 cc 76 80 e1 b6 45 4d c7 cd 84 ce b4 52 79 74 cd e6 d7 d1 9c ad ef 63 6c 0f f7 05 e4 4d 1a d3 cb 9c d2 51 b5 61 cb ff 7c ee c7 bc 5e 15 a3 f2 52 0f bb 32 pre master secret[48]: 03 00 ff 84 56 6d a0 fb cc fd c6 c8 20 d5 f0 65 18 87 b0 44 45 9c e3 92 f0 4d 32 cd 41 85 10 24 cb 7a b3 01 36 3d 93 27 12 a4 7e 00 29 96 59 d8 master secret[48]: 1e db 35 95 b8 18 b3 52 58 f3 07 3f e6 af 8a a6 ab c3 a4 ed 66 3a 46 86 b6 e5 49 2a 7c f7 8c c2 ac 22 bb 13 15 0f d8 62 a2 39 23 7b c2 ff 28 fb key expansion[136]: 11 60 e4 e1 74 e9 a1 cf 67 f9 b7 bc ef bc a7 c7 b3 f7 33 aa b2 42 d0 1c a6 4e fb e9 9b 13 dd 29 63 aa 17 1f 47 71 95 71 08 e0 4b 8e e1 da 7b 4a 5a f3 c2 32 bd e0 a5 82 6d 14 44 3a d6 cb 2d c0 7d 57 be a8 37 de 5d d9 a1 07 fd 1b 22 71 b9 4b 7a 1e 0f 70 37 14 97 0a f0 db 98 3b 7b 74 e3 2d 51 66 2e 31 68 90 ac 6f e6 53 3c c9 5e 48 0c 05 bc 9f 92 e7 f9 91 98 f5 95 1c c4 bf d9 cb 26 ef 35 70 5e ad 21 22 3e f6 Client MAC key[20]: 11 60 e4 e1 74 e9 a1 cf 67 f9 b7 bc ef bc a7 c7 b3 f7 33 aa Server MAC key[20]: b2 42 d0 1c a6 4e fb e9 9b 13 dd 29 63 aa 17 1f 47 71 95 71 Client Write key[32]: 08 e0 4b 8e e1 da 7b 4a 5a f3 c2 32 bd e0 a5 82 6d 14 44 3a d6 cb 2d c0 7d 57 be a8 37 de 5d d9 Server Write key[32]: a1 07 fd 1b 22 71 b9 4b 7a 1e 0f 70 37 14 97 0a f0 db 98 3b 7b 74 e3 2d 51 66 2e 31 68 90 ac 6f Client Write IV[16]: e6 53 3c c9 5e 48 0c 05 bc 9f 92 e7 f9 91 98 f5 Server Write IV[16]: 95 1c c4 bf d9 cb 26 ef 35 70 5e ad 21 22 3e f6
Until recently the dissection of the ClientKeyExchange was like this(version 1.6 and below): TLSv1 Record Layer: Handshake Protocol: Client Key Exchange Content Type: Handshake (22) Version: TLS 1.0 (0x0301) Length: 134 Handshake Protocol: Client Key Exchange Handshake Type: Client Key Exchange (16) Length: 130 But if you use this verison(1.7.2 upwards) the key dissection will be like this: TLSv1 Record Layer: Handshake Protocol: Client Key Exchange Content Type: Handshake (22) Version: TLS 1.0 (0x0301) Length: 134 Handshake Protocol: Client Key Exchange Handshake Type: Client Key Exchange (16) Length: 130 RSA Encrypted PreMaster Secret Encrypted PreMaster length: 128 Encrypted PreMaster: 761b1beac35e59de9a3bb9f74ebf9109b738e8ad346 You can see the encrypted pre-master:)
Awesome write up here explaining how SSL works, notice at no time during this handshake is the private key ever sent over the wire. http://4orensics.wordpress.com/2011/10/21/ssl-in-a-nutshell/ Long story short there is no way to decrypt SSL streams without the server's private key (unless you work for the NSA or something), however you may want to look into getting in between the server and client during the handshake and if the user does not check the validity of the certificate that is presented you are in business. Here is a tool that can do that for you among many others http://mitmproxy.org/ Of note I highly recommend the sans reading room article on SSL Mitm(Man in the Middle) attacks.