This note shows how to access and decode RSA public keys in various formats from .NET for digital signature and asymmetric public-key encryption use. Compatibility between .NET Framework 1.1 and Java 2 is discussed.
RSA PKCS#1 Digital Signature:
For the same RSA keypair, hash algorithm and byte content, digital signatures generated by java.security.Signature.Sign() with
an RSA provider, are identical to those generated by .NET Framework 1.1
System.Security.Cryptography.RSAPKCS1SignatureFormatter.CreateSignature().
Both Java and .NET generate a PKCS #1 version 1.5 signature. By comparison, CryptoAPI
CryptSignHash() generates the same PKCS #1 signature block, but in reversed (little-endian) order.
ASN.1 Encoded RSA Public Key formats:
There are two commonly used ASN.1 encoded "public key" formats.
Sample hex-dumps of ASN.1 encoded SubjectPublicKeyInfo and RSAPublicKey blobs are shown below:
X.509 SubjectPublicKeyInfo public key format [162 bytes]
30 81 9F 30 0D 06 09 2A 86 48 86 F7 0D 01 01 01
05 00 03 81 8D 00 30 81 89 02 81 81 00 C2 AC 3D
E3 D3 43 2C 88 4D 0C 7C 4C 3D AC 14 95 20 A6 45
11 B6 D3 BC 90 3F 74 DB 44 C8 BA F9 E9 60 E2 CB
48 59 4D 47 DF 2A E3 08 14 2D 2E 52 56 B1 E5 5E
A2 D4 13 CF A5 B0 42 C3 35 5D D8 97 9E C8 95 8D
8D EC C0 2F 1E 64 E1 C6 9E 96 E8 A9 AA D1 A3 9A
90 7B F6 33 71 BB B1 B5 D5 4D 05 3F C5 67 F2 26
74 C2 F6 69 78 67 B0 FC 0D 3C 8A CC B4 C6 B8 A1
DD 76 72 31 45 2B 56 72 84 83 BF 8F A1 02 03 01
00 01
RSAPublicKey PKCS #1 format [140 bytes]
30 81 89 02 81 81 00 C2 AC 3D E3 D3 43 2C 88 4D
0C 7C 4C 3D AC 14 95 20 A6 45 11 B6 D3 BC 90 3F
74 DB 44 C8 BA F9 E9 60 E2 CB 48 59 4D 47 DF 2A
E3 08 14 2D 2E 52 56 B1 E5 5E A2 D4 13 CF A5 B0
42 C3 35 5D D8 97 9E C8 95 8D 8D EC C0 2F 1E 64
E1 C6 9E 96 E8 A9 AA D1 A3 9A 90 7B F6 33 71 BB
B1 B5 D5 4D 05 3F C5 67 F2 26 74 C2 F6 69 78 67
B0 FC 0D 3C 8A CC B4 C6 B8 A1 DD 76 72 31 45 2B
56 72 84 83 BF 8F A1 02 03 01 00 01
A partial ASN.1 dump of the certificate containing this public key is shown
below. The entire displayed ASN.1 corresponds to the SubjectPublicKeyInfo data.
The red sub-data is the RSAPublicKey encodeded data:
0235 30 9F: SEQUENCE { 0238 30 D: SEQUENCE { 023A 06 9: OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1) 0245 05 0: NULL : } 0247 03 8D: BIT STRING 0 unused bits, encapsulates { 024B 30 89: SEQUENCE { 024E 02 81: INTEGER : 00 C2 AC 3D E3 D3 43 2C 88 4D 0C 7C 4C 3D AC 14 : 95 20 A6 45 11 B6 D3 BC 90 3F 74 DB 44 C8 BA F9 : E9 60 E2 CB 48 59 4D 47 DF 2A E3 08 14 2D 2E 52 : 56 B1 E5 5E A2 D4 13 CF A5 B0 42 C3 35 5D D8 97 : 9E C8 95 8D 8D EC C0 2F 1E 64 E1 C6 9E 96 E8 A9 : AA D1 A3 9A 90 7B F6 33 71 BB B1 B5 D5 4D 05 3F : C5 67 F2 26 74 C2 F6 69 78 67 B0 FC 0D 3C 8A CC : B4 C6 B8 A1 DD 76 72 31 45 2B 56 72 84 83 BF 8F : A1 02D2 02 3: INTEGER 65537 : } : } : }
Microsoft CryptoAPI Public Key formats:
CryptoAPI allows exporting keys in unencoded format. For public keys, the
PUBLICKEYBLOB format
can be easily parsed by any application to obtain the RSA public key parameters.
The CryptoAPI PUBLICKEYBLOB can be obtained several ways. Here are a few:
Note that CryptoAPI and .NET unencoded public key structures store the modulus and exponent in LITTLE-endian byte order.
Public key data sizes:
As a summary, here are the byte lengths for public key structures for 1024 bit RSA keys:
Using ASN.1 encoded or CryptoAPI PUBLICKEYBLOB public keys in .NET:
Public key parameters can be used to either verify RSA digital signatures, or to asymmetric-encrypt
data using the recipients public key. To use various format public key files form .NET, the
public key modulus and exponent parameters must be extracted from the keyblobs.
One way to do this is:
RSAPubKeyData.cs is a utility class with methods to decode any of the public-key file blob formats discussed above:
The following utilities may also be useful:
DecodeBlob.exe
is a native (C) console application which decodes a Java exported public key file,
and writes a CryptoAPI PUBLICKEYBLOB file publickeyblobout to the current directory.
Sample output
RSAKeyblob
is a .NET console utility which reads and parses an RSA
CryptoAPI PUBLICKEYBLOB file and displays public key details including RSA bit size,
exponent and modulus value (in big-endian byte order). Sample output
DecodeCertKey
is a .NET console utility which reads any local X.509 v3 certificate file,
decodes the PUBLICKEYBLOB, displays the public key exponent and modulus in big-endian order and
uses the public key data to instantiate an instance of .NET RSACryptoServiceProvider.
Michel I. Gallant
neutron@istar.ca