
Comments and Discussions



Hi Dudi. Thanks for the great article. It doesn't seem to be possible to add a .net 4 assembly to SQL Server 2008. Your old code should work though. Do you still have that available? Take care, Hennie.





Hi Dudi Bedner!
I found some cases that the code failed with specific keypair/plaintext.
I used this private key:
"<RSAKeyValue><Modulus>2KNBWU7v7JTt3qQxSh8hh6gKwIbCp2DYp5SZB7lQuzZukSDzYoy0eBDdmjFGX/sN2KIloVDMLneo8Lg+0YRRc11usV+qMWtFCRIHzxeA6n+gadVsgCqblCoiKYy8aN3eodcrUIJXCG6jNnBBQxc6aGUIBOYBrTfUjZ1TsH/FhRk=</Modulus><Exponent>AQAB</Exponent><P>69px/444P+cIaKuqljaPxrRL/hvxXpx8wni4SpriLPLrhM9UZISc3fk8U8Vo6+63V0wJquTaP7RaaSm3VOCL3w==</P><Q>6yScSEG2YwSIVlzy5FBLFBBEXQpCZQOjSjenjvu4PP3950ikU4WqBj9zjnAYwgHahHev6x4LWCRcTCteoXSOBw==</Q><DP>LBw5z+LocEMkVncsu1VPBIm54LeXJ+u6haCQTxuyi1ePZtJj5TzMHdO8TaqRGfcWgRQuhrCwhNOVSS/NIumwHw==</DP><DQ>ZL7v0qmM6kmz3ETAsH+SW0tI7xAJOFxhptfHi6Rf4In2MhTWiw52tWyUJw/yG5VNuXnKPpNFywLxJJVkWwqkGw==</DQ><InverseQ>Q7uyU8ELBhPc41+JFH9QYTiApyeJwpsZM5mUJd2nYdvZ9D9c8eFWF1NJJJrXM8CNUT9ayXnrfesQDGIlqRvJwA==</InverseQ><D>dxH8GA839cvBli6e3MORlVM6Xal0EbU8P5eAKOulQNDhIql+vHrjsl5qvpY4vQZrDNfKYQjcwOmKFIzgEh5s+T3P3E9+6lfePTE5DFbgZnrRT45SVyn/KUoJwbfSns+/KC7KGeWaHIJsnHo0YeDx8ZXO0KouOiBnti4bFWtXO8U=</D></RSAKeyValue>"
...to encrypt the plaintext:
34B273C6
Then I decrypted the cipher using the public key but the result was not match the plaintext.
You can see more in the attached file.
Soucre code: Download
modified 26Feb14 6:29am.





As far as I understand, your code signs the data with the private key and then the recipient checks the signature with the public key.
What if you really need to encrypt the data with the private key and decrypt it with the public key?
I am trying to do this with RSACryptoServiceProvider (because I also want the data to be encrypted, not only signed) and I get an exception ("Error occurred while decoding OAEP padding.").
Any quick ideas?
Notes :
 I encrypt/decrypt with `fOAEP` set to `true`.
 I use a 1024 key size and the data that I want to encrypt are no longer than 65 bytes.
 I load my keys from XML.
I think the data is short enough for not to create any problems, but for some reason it does...
Anyway, if you don't have any quick ideas I could probably go with the signature approach.
Kostas





Oh, the more I read, the more I start to believe that your code is what I am looking for...
But why doesn't this work on RSACryptoServiceProvider ???
By the way, I think that it is better if the Random inside your AddPadding() goes to class scope and becomes static.
If Random uses the time of the clock to get initialized you might get the same padding bytes many times (I think).
EDIT :
Yep, here you go (http://msdn.microsoft.com/enus/library/System.Random.aspx[^]):
The random number generation starts from a seed value. If the same seed is used repeatedly, the same series of numbers is generated. One way to produce different sequences is to make the seed value timedependent, thereby producing a different series with each new instance of Random. By default, the parameterless constructor of the Random class uses the system clock to generate its seed value, while its parameterized constructor can take an Int32 value based on the number of ticks in the current time. However, because the clock has finite resolution, using the parameterless constructor to create different Random objects in close succession creates random number generators that produce identical sequences of random numbers. The following example illustrates that two Random objects that are instantiated in close succession generate an identical series of random numbers.
Kostas
modified 4Aug13 5:38am.





Hi!
In your old version from 2009 I was able to encrypt usign the public key and decrypt using the private key.
The new version lacks those methods.
For a true twoway crypto I will need those two.
I tried implementing them but I get garbage when decrypting. What am I missing?
Public ENCRYPT:
BigInteger numData = GetBig( AddPadding( data ) );
RSAParameters rsaParams = rsa.ExportParameters( false );
//BigInteger D = GetBig( rsaParams.D ); //only for private key
BigInteger Exponent = GetBig( rsaParams.Exponent );
BigInteger Modulus = GetBig( rsaParams.Modulus );
BigInteger encData = BigInteger.ModPow( numData, Exponent, Modulus );
Private DECRYPT:
BigInteger numEncData = new BigInteger( cipherData );
RSAParameters rsaParams = rsa.ExportParameters( true );
BigInteger D = GetBig( rsaParams.D );
//BigInteger Exponent = GetBig( rsaParams.Exponent );
BigInteger Modulus = GetBig( rsaParams.Modulus );
BigInteger decData = BigInteger.ModPow( numEncData, D, Modulus );
byte[] data = decData.ToByteArray();
byte[] result = new byte[ data.Length  1 ];
Array.Copy( data, result, result.Length );
result = RemovePadding( result );
Array.Reverse( result );
return result;
Can you help? I would appreciate it very much!





Any reason not to use the the builtin RSACryptoServiceProvider methods
for public encryption and private decryption?
var rsa = new RSACryptoServiceProvider();
byte[] secretData = new byte[] { }; byte[] encrypted = rsa.Encrypt(secretData, true); byte[] decrypted = rsa.Decrypt(encrypted, true);






Thank you for this piece of code and the sample. I am very new to encryption/certificates and I have to encrypt/decrypt creditcard data store within a SQLServer DB.
Is it possible to load the key pairs from a certificate store (X509) ? ...and if so, can you give me some advice for how to do it ?
Thanks in advance.
cu., drice aka. A. Thiede






Is this solution compatible with the PHP functions openssl_private_encrypt and openssl_private_decrypt?





Encoding.UTF8.GetBytes() Encoding.UTF8.GetString() method not worked properly.
error message "The data to be decrypted exceeds the maximum for this modulus of 128 bytes."





Encoding.UTF8.GetBytes("your string to encrypt").Length
Should not exceed the length of the key,
create a RSACryptoServiceProvider object with a larger key if it does.
If this doesn't help, post the full stack trace and the string parameter.
Regards,
Dudi.






Nice program...I do BIOS work and would like to add RSA2048 support to help verify some BIOS related security data I have. I don't have a lot of experience with .net for c#, but I rebuilt the project with a larger big interger size, and I can indeed load RSA2048 keys and get a Private ey encryption answer now...
But...the Public Key exponent still shows the value 0x101, and not the value in the source xml key file which is 0x10001, so I suspect that the result might not be correct...and also...that there might be additional changes needed to fully support RSA 2048 encryption/decryption.
Can anyone help me with this???
Thaanks a bunch....





Update: After changing this line below to read...
private const int maxLength = 200;
...to accomodate larger BigIntegers, and then rebuilding...even though the Public Key exponent displays wrong (as 0x101 instead of 0x10001), the RSA=2048 Public Key decryption works fine...so far the results match those of the library I'm comparing against(!!!)
Thanks again for the great work.....





i Have this code how can i decode it?
êêrmTp–؛î{Vژٹغ.1w»·£lعهةہR}‹gے8[‰¶ُkçًےAiaE*n–ًع¥خَï !ھm¯†إنـrè¬cqْ2r—ة>‰…qB[1:”qü”
ةpؤچ¸N/تl@®k(éجuَbL“ù†
Thanks in advance





the decrypted string shown is not the same as original. weird symbols are shown in the decrypted message.Kindly provide a solution for the same.







"We've demonstrated that a faultbased attack on the RSA algorithm is possible,"
said Professor Todd Austin said. "Hopefully, this will cause manufacturers to make a few
small changes to their implementation of the algorithm. RSA is a good algorithm and I think,
ultimately, it will survive this type of attack.
End quote
Anyway, I'm not sure whether that article is relevant to this one...
modified 8Feb12 13:11pm.





Hi
This is a good project  giving lots of insights.
My two issues:
1. Is it possible to system.numeric.biginteger ?
2. should some random padding be given even to string messages ?
is it done in case rsacryptoserviceprovider ?
Thanks
Abhishek






Cool. Will look forward to the new project.
For padding may be you should implement PKCSv1.5 or OAEP
(in line with rsacryptoserviceprovider)





how RSA encryption used is used for encrypting images?





RSAEncryption encrypt = new RSAEncryption();
encrypt.LoadPrivateKeyFromXml(...);
byte[] aOrigBytes = ...;
byte[] aEncryptedBytes = encrypt.PrivateEncryption(aOrigBytes);
byte[] aDecryptedBytes = encrypt.PublicDecryption(aEncryptedBytes);
if (aOrigBytes.SequenceEqual(aDecryptedBytes))
Console.WriteLine("Correct!");
else
Console.WriteLine("Wrong!");
It always says "Wrong!"






Thanks! I needed something to encrypt with a private key!
A small enhancement  the PrivateEncryption() and PublicEncryption() methods can be replaced with a single method.
public enum KeyType
{
Private,
Public
}
.
.
.
public byte[] Crypt(byte[] data, KeyType type)
{
BigInteger keyExp = new BigInteger(1);
if (KeyType.Private == type)
{
if (!IsPrivateKeyLoaded) throw new CryptographicException
("Private Key must be loaded before Encrypting with the Private Key!");
keyExp = D; }
else if (KeyType.Public == type)
{
if (!IsPublicKeyLoaded) throw new CryptographicException
("Public Key must be loaded before Encrypting with the Public Key!");
keyExp = Exponent; }
else
{
throw new CryptographicException("Incorrect Key type. Must be Private or Public.");
}
BigInteger number = new BigInteger(data);
BigInteger cryptNumber = number.modPow(keyExp, Modulus);
return cryptNumber.getBytes();
}
Then call Crypt() passing in the KeyType to be use for Encrypting/Decrypting.
The library can also be enhanced with the Parsing strong name signatures generated with sn.exe[^] library to get the private and public key from a .snk file.
The leading 0 bug was solved for me by switching from UnicodeEncoding to UTF8Encoding instead of adding padding. I only need it for text, so that worked.
Thanks,
Daniel





Even with UTF8 ecoding private encryption/decryption of 0bad31c96c344015b0e99ebf00c4ed66 failed (one guid in thousands) so it might be usefull to check your code against that guid





'if' here? imho it is better to have two methods versus the extra bool argument ... just my 2 cents, nice article by the way







The question is:
The given value is your CA private key. Use it to sign and Base64 encode the word: enigma.
Retain your private key.
I have signed the certificate in openssl and I have retrieved the output but I can't find out what the value for the modulas is.
Thanks





Can it interoperate with rsacryptoserviceprovider ?
Encrypt/SignHash... ?
I don't understand what's rsacryptoserviceprovider.encrypt() doing  it always returns different results for the same input...






Can you provide an example ?
Thanks





In shared hosting you have no access to the machine key, so the first call to _rsa.FromXmlString(xml_string) fails in server side code. It would be SO appreciated if you added reading (and saving) a PEM key file to your program  after all, you must run across that divide at times, being a crypto guru. There are lots of good code examples out there, such as of Michel I. Gallant of Java Science Consulting, but they are trying to be allencompassing and hard to include in a simple Win app. Also, is there a flag somewhere to indicate padding and big endian true/false by looking at the key data?
Gracias,
Walter Knopf (semiretired, struggling...)
I guess you got two votes of 5 from me, deservedly so





Interop with OpenSSL will be great





works flawlessly out of the box, also lets a cryptography beginner see the difference between the XML representation and the key values.





Good morning Dudi Bender!
I'm trying to encrypt a string using the RSACryptoServiceProvider and I'd like to know if there's a way to import a file with .key extension (my private key) to use it to encrypt. I've readed it's possible to load a xml file with the private key (as you said) and also it's possible to load a PKCS file but I haven't found something about the .key files.
Thanks in advance.





I used the proveded classes to do an assignement on Dual Signature. And it was working perfect. Thank you Israel.





Hi i have gone through ur article.It is good. Can u please give some examples of how to encrypt and decrypt a file using RSA, that would be helpful.





RSA Encryption  due to it's huge structure  is usually done on small chunks of data,
so encrypt a file is not recommended even if possible (depends on it's size).
To accomplish your goal, you should symmetrically (AES is a good choice) encrypt
the file with some random key, and then encrypt the key with your public RSA key,
and send both (Symmetric encrypted file, and asymmetric encrypted key) to the receiver.
Whomever got the private RSA key, can decrypt the symmetric key, and then decrypt
the file  achieving the requested results.
good lock!





Hi Dudi Bedner,
Thanks for your reply but if u can help me with some sample to encrypt and decrypt a file using RSA (Size less then 5 MB Max) other wise i would change some alternate methods as u suggested.
Thanks and Regards
Ganesh.





Hi Dudi Bedner,
I have followed your advise and encrypted the file using AES, and now my problem is that i am encrypting the password using RSA private key and stored the encrypted value in sql and now i want to decrypt the encrypted value how should i do since it is a client/server application and could you suggest some thing or u need my code to analyze.
Waiting for your reply
Regards
Ganesh.





Hello Ganesht
Can not advise you regarding the design and implementation of your application,
without really diving into it (and this is something I don't wanna do ).
If you could focus your problem to one single point, and explain it clearly,
maybe I can help solving it.
Have a great day!
Dudi.





When using the code, make sure to add the bug fix mentioned in the previous posts.





Sorry, for the delayed reply i have a problem in my computer.
Class file
Namespace rsa
Public Class clsCryptography
Private RSA As RSACryptoServiceProvider
Public PublicKey As String
Public PrivateKey As String
Public function Encrypt(Data as byte(),PublicKeyIn as _
string) as Byte()
RSA.FromXmlString(PublicKeyIn)
End function
Public Function Decrypt(Data as byte(),PrivateKeyIn as_
string) as Byte()
RSA.FromXmlString(PrivateKeyIn)
Return RSA.Decrypt(Data,False)
End Function
End Class
End Namespace
In the Form
imports System
imports System.Security.Cryptography
Public Class Form1
Inherits System.Windows.Forms.Form
Private clsRSA As clsCryptography = New clsCryptography()
Private Decrypted() As Byte
Private Encrypted() As Byte
Public Sub New()
Dim cspParams As CspParameters = New CspParameters()
cspParams.Flags = CspProviderFlags.UseMachineKeyStore
RSA = New RSACryptoServiceProvider(cspParams)
PublicKey = RSA.ToXmlString(False)
PrivateKey = RSA.ToXmlString(True)
End Sub
Private Sub btnEncrypt_Click(ByVal sender As Object, _
ByVal e As System.EventArgs)
Dim PlainText() As Byte = System.Text.Encoding.Encoding.ASCII.GetBytes (tbWorking.Text)
Encrypted = clsRSA.Encrypt(PlainText, clsRSA.PublicKey)
tbWorking.Text = System.Text.Encoding.ASCII.GetString(Encrypted)
End Sub
Private Sub btnDecrypt_Click(ByVal sender As Object,ByVal e As System.EventArgs)
Decrypted = clsRSA.Decrypt(Encrypted, clsRSA.PrivateKey)
tbWorking.Text = _
System.Text.Encoding.ASCII.GetString(Decrypted)
End Sub
I have used the following example and i want to encrypt the data on the server side and decrypt the data in client side, so i am storing the encrypted value in sql and i need to decrypt the stored ecrypted value in client side so could u suggest how i can proceed since i am getting struck in decryption.
Waiting for your reply.





The given value is your CA private key. Use it to sign and Base64 encode the word: enigma.
Retain your private key.
=========================================================================
I have private key for it but not well vesed how to use it tired this COMMAND: openssl rsautl sign in message.txt inkey private_key.txt out answer
BUT KNOW WHERE TO GO FROM THERE TO RETRIEVE THE ANSWER FOR THIS QUESTION.





Hello Mr.Dudi Bedner, my name is Angel i'm form Mexico and i have a problem with this things about certificates, you'll see i have a .key file and a .cer file, and what i have to do is to sign a string with the .key file which is mi private key, but i don't have any idea how to do that. I hope that you can give me some tips of how can i solve this
P.S
I apologize for my bad english..... Greetings from Mexico





First of all, let me say that I found this article very usefull. I had a need to encrypt something with the private key, and I went nut trying to do it with the NET implentation of RSA cryptographic.
Thanks a lot!
The way RSAEncryption is currently implemented will not work if you pass a byte array larger than BigInteger.maxLength * 4 ( 640 bytes).
I made the following changes/addition to your class:
Made BigInteger.maxLength = 128 to accomodate a key length of 128*4*8 = 4096 bits
add a block size variable to the RSAEncryption class:
private int RSA_Block_Size = 128; //bytes
Set the value of RSA_Block_Size variable to the key modulus array lenght inside the functions:
public void LoadPublicFromXml(string publicPath)
public void LoadPrivateFromXml(string privatePath)
RSA_Block_Size = rsaParams.Modulus.Length;
Change the encrypt/decrypt implementation as follows:
// Encrypt data using private key
public byte[] PrivateEncryption(byte[] data)
{
if (!IsPrivateKeyLoaded) // is the private key has been loaded?
throw new CryptographicException
("Private Key must be loaded before using the Private Encryption method!");
MemoryStream ms = new MemoryStream();
int blocks = data.Length / RSA_Block_Size;
int left = data.Length % RSA_Block_Size;
byte[] temp = new byte[RSA_Block_Size];
BigInteger bnData=null;
BigInteger encData=null;
for (int i = 0; i < blocks; i++)
{
// Converting the byte array data into a BigInteger instance
Buffer.BlockCopy(data, RSA_Block_Size * i, temp, 0, RSA_Block_Size);
bnData = new BigInteger(temp);
// (bnData ^ D) % Modulus  This Encrypt the data using the private Exponent: D
encData = bnData.modPow(D, Modulus);
temp=encData.getBytes();
ms.Write(temp,0,temp.Length);
}
if (left > 0)
{
temp = new byte[left];
Buffer.BlockCopy(data, RSA_Block_Size * blocks, temp, 0, left);
bnData = new BigInteger(temp);
// (bnData ^ D) % Modulus  This Encrypt the data using the private Exponent: D
encData = bnData.modPow(D, Modulus);
temp = encData.getBytes();
ms.Write(temp, 0, temp.Length);
}
temp = new byte[ms.Length];
Buffer.BlockCopy(ms.GetBuffer(), 0, temp, 0, temp.Length);
return temp;
}
// Decrypt data using public key (for data encrypted with private key)
public byte[] PublicDecryption(byte[] encryptedData)
{
if (!IsPublicKeyLoaded) // is the public key has been loaded?
throw new CryptographicException
("Public Key must be loaded before using the Public Deccryption method!");
MemoryStream ms = new MemoryStream();
int blocks = encryptedData.Length / RSA_Block_Size;
int left = encryptedData.Length % RSA_Block_Size;
byte[] temp = new byte[RSA_Block_Size];
BigInteger bnData = null;
BigInteger encData = null;
for (int i = 0; i < blocks; i++)
{
// Converting the encrypted data byte array data into a BigInteger instance
Buffer.BlockCopy(encryptedData, RSA_Block_Size * i, temp, 0, RSA_Block_Size);
encData = new BigInteger(temp);
// (encData ^ Exponent) % Modulus  This Decrypt the data using the public Exponent
bnData = encData.modPow(Exponent, Modulus);
temp = bnData.getBytes();
ms.Write(temp, 0, temp.Length);
}
if (left > 0)
{
temp = new byte[left];
Buffer.BlockCopy(encryptedData, RSA_Block_Size * blocks, temp, 0, left);
encData = new BigInteger(temp);
// (encData ^ Exponent) % Modulus  This Decrypt the data using the public Exponent
bnData = encData.modPow(Exponent, Modulus);
temp = bnData.getBytes();
ms.Write(temp, 0, temp.Length);
}
temp = new byte[ms.Length];
Buffer.BlockCopy(ms.GetBuffer(), 0, temp, 0, temp.Length);
return temp;
}







General News Suggestion Question Bug Answer Joke Rant Admin Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

How to encrypt data using a private key in .NET.
Type  Article 
Licence  CPOL 
First Posted  4 Aug 2009 
Views  124,874 
Downloads  18,780 
Bookmarked  123 times 

