I created a public and private key using openssl in the cmd line of a linux machine using the following commands:
openssl genrsa -out rsa_1024_priv.pem 1024
openssl rsa -pubout -in rsa_1024_priv.pem -out rsa_1024_pub.pem
Now I want to be able to decrypt data in VB.NET that was already encrypted with the public key.
I am using the method found in the MSDN documentation for decryption. I am trying to set the RSAParameters to pass in to the RSADecrypt
method, but I'm not really sure what goes into each field.
Whenever I try running the code I get the following error:
System.Security.Cryptography.CryptographicException: Bad Data.
at System.Security.Cryptography.CryptographicException.ThrowCryptographicExce
ption(Int32 hr)
at System.Security.Cryptography.Utils._ImportKey(SafeProvHandle hCSP, Int32 k
eyNumber, CspProviderFlags flags, Object cspObject, SafeKeyHandle& hKey)
at System.Security.Cryptography.RSACryptoServiceProvider.ImportParameters(RSA
Parameters parameters)
at Decryptor.Module1.RSADecrypt(Byte[] DataToDecrypt, RSAParameters RSAKeyInf
o, Boolean DoOAEPPadding) in C:\Users\yhorowitz\AppData\Local\Temporary Projects
\Decryptor\Module1.vb:line 30
The error is being thrown on this line RSA.ImportParameters(RSAKeyInfo)
in the RSADecrypt
method
This is the code I have so far:
Imports System.Security.Cryptography
Imports System.Text
Module Module1
Dim encoder As New UTF8Encoding
Sub Main()
Dim MyPrivateKey As String = "" 'Removed
Dim MyPublicKey As String = "" 'Removed
Dim MyModulus as String = "" 'Removed
Dim DataToDecrypt() As Byte = Convert.FromBase64String("CourNHBC55DgGtBZU6Ahtm0emywGi5hWo5/h9zD6A/NASKMpZ/A5GCU8G5TNTMgJQxVFsabbdeuNhf4VQzBuFqewuD8eD7MwpJvjmuPfrs7xcEzOrwbF549v0PHv/nfN+03winW6s3ecnv1dm0TctQgqsauEuvXu2PMVEFivqPo=")
Dim params As RSAParameters = New RSAParameters()
params.Exponent = Convert.FromBase64String(MyPublicKey)
params.D = Convert.FromBase64String(MyPrivateKey)
params.Modulus = Convert.FromBase64String(MyModulus)
Console.WriteLine(Convert.ToString(RSADecrypt(DataToDecrypt, params, False)))
Console.Read()
End Sub
Public Function RSADecrypt(ByVal DataToDecrypt() As Byte, ByVal RSAKeyInfo As RSAParameters, ByVal DoOAEPPadding As Boolean) As Byte()
Try
Dim decryptedData() As Byte
'Create a new instance of RSACryptoServiceProvider.
Using RSA As New RSACryptoServiceProvider(1024)
RSA.ImportParameters(RSAKeyInfo)
decryptedData = RSA.Decrypt(DataToDecrypt, DoOAEPPadding)
End Using
Return decryptedData
Catch e As CryptographicException
Console.WriteLine(e.ToString())
Return Nothing
End Try
End Function
End Module
Under the most strict of senses, the RSA algorithm requires
- Public key (n (aka Modulus), e)
- Private key (n, d)
And some libraries, like OpenSSL, will work with just the (n, e, d) triplet.
But Windows CAPI (and probably Windows CNG) pretty much ignores d
, because it's much more efficient to do RSA using the Chinese Remainder Theorem (CRT).
So RSACryptoServiceProvider
(and RSACng
(net46+, netcoreapp10+), and RSAOpenSsl
(netcoreapp10+)) all require a fully populated RSAParameters
structure for private keys.
For public-only, you can set just Modulus
and Exponent
.
For private, you need to set all of the fields, and they must have the following characteristics:
Modulus[0]
must not be 0
.
D
and Modulus
must be the same number of bytes.
E
is whatever it is, but E[0]
must not be 0
.
P
, Q
, DP
, DQ
, InverseQ
must all be the same number of bytes, and that number must be exactly half the size of Modulus
(round up, if it matters).
To line terms up from OpenSSL's RSA pretty-print to RSAParameters:
-----------------------------------
| OpenSSL | RSAParameters |
-----------------------------------
| modulus | Modulus |
| publicExponent | Exponent |
| privateExponent | D |
| prime1 | P |
| prime2 | Q |
| exponent1 | DP |
| exponent2 | DQ |
| coefficient | InverseQ |
-----------------------------------
For an example of converted data (on a key already disclosed as a test key), see https://github.com/dotnet/corefx/blob/193d663393b75f83a447a635523a6e84454d9482/src/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/TestData.cs#L179-L285, which is the same as this OpenSSL dump:
$ openssl rsa -in rsa1032.key -text -noout
Private-Key: (1032 bit)
modulus:
00:bc:ac:b1:a5:34:9d:7b:35:a5:80:ac:3b:39:98:
eb:15:eb:f9:00:ec:b3:29:bf:1f:75:71:7a:00:b2:
19:9c:8a:18:d7:91:b5:92:b7:ec:52:bd:5a:f2:db:
0d:3b:63:5f:05:95:75:3d:ff:7b:a7:c9:87:2d:bf:
7e:32:26:de:f4:4a:07:ca:56:8d:10:17:99:2c:2b:
41:bf:e5:ec:35:70:82:4c:f1:f4:b1:59:19:fe:d5:
13:fd:a5:62:04:af:20:34:a2:d0:8f:f0:4c:2c:ca:
49:d1:68:fa:03:fa:2f:a3:2f:cc:d3:48:4c:15:f0:
a2:e5:46:7c:76:fc:76:0b:55:09
publicExponent: 65537 (0x10001)
privateExponent:
00:9e:59:25:e2:ec:6c:bb:4a:83:f3:a1:19:37:b6:
e2:9e:8c:64:78:65:2f:dc:fa:9d:d1:78:82:97:70:
e2:53:e2:07:05:6d:32:01:c8:41:1c:13:f5:ef:da:
ee:99:08:46:68:ae:4e:2e:d1:6c:1b:9e:e4:c7:fd:
6e:51:73:14:2d:c5:9f:c6:45:a4:c2:e6:65:5d:ac:
e6:71:b3:00:de:0d:7b:b5:2d:68:a8:60:26:c1:8f:
02:47:26:e7:71:bd:04:81:99:44:2f:03:42:70:96:
58:ef:f6:4a:e4:2e:a4:17:32:47:ec:d2:4a:86:29:
9e:8b:9d:11:52:00:02:c8:f5:f1
prime1:
0e:15:30:0a:9d:34:ba:37:b6:bd:a8:31:bc:67:27:
b2:f7:f6:d0:ef:b7:b3:3a:99:c9:af:28:cf:d6:25:
e2:45:a5:4f:25:1b:78:4c:47:91:ad:a5:85:ad:b7:
11:d9:30:0a:3d:52:b4:50:cc:30:7f:55:d3:1e:12:
17:b9:ff:d7:45
prime2:
0d:65:c6:0d:e8:b6:f5:4a:77:56:fd:1c:cb:a7:6c:
e4:1e:f4:46:d0:24:03:1e:e9:c5:a4:09:31:b0:73:
36:cf:ed:35:a8:ee:58:0e:19:db:85:92:cb:0f:26:
6e:c6:90:28:eb:9e:98:e3:e8:4f:f1:a4:59:a8:a2:
68:60:a6:10:f5
exponent1:
0d:9d:b4:be:7e:73:0d:9d:72:a5:7b:2a:e3:73:85:
71:c7:c8:2f:09:a7:be:b5:e9:1d:94:aa:cc:10:cc:
be:33:02:7b:3c:70:8b:e6:8c:c8:30:71:ba:87:54:
5b:00:78:2f:5e:4d:49:a4:59:58:86:b5:6f:93:42:
81:08:48:72:55
exponent2:
0c:f6:fb:dd:e1:e1:8b:25:70:af:21:69:88:3a:90:
c9:80:9a:eb:1b:e8:7d:8c:a0:b4:bd:b4:97:fd:24:
c1:5a:1d:36:dc:2f:29:cf:1b:7e:af:98:0a:20:b3:
14:67:da:81:7e:e1:8f:1a:9d:69:1f:71:e7:c1:a4:
c8:55:1e:df:31
coefficient:
01:0c:e9:93:6e:96:fb:ad:f8:72:40:cc:41:9d:01:
08:1b:b6:7c:98:1d:44:31:4e:58:58:3a:c7:fe:93:
79:ea:02:72:e6:c4:c7:c1:46:38:e1:d5:ec:e7:84:
0d:db:15:a1:2d:70:54:a4:18:f8:76:4f:a5:4c:e1:
34:eb:d2:63:5e