ubergeek2

Hi,

I’m trying to encrypt/decrypt data using RSACryptoServiceProvider.Encrypt() and RSACryptoServiceProvider.Decrypt(). Here is the code I am using:

using System;

using System.Collections.Generic;

using System.Text;

using System.IO;

using System.Security.Cryptography;

namespace CryptoLibrary

{

public class RSAEncryption

{

// Key info.

private RSAParameters keyinfo = new RSAParameters();

public RSAParameters KeyInfo { get { return keyinfo; } set { keyinfo = value; } }

// Unicode Encoding.

UnicodeEncoding Unicode = new UnicodeEncoding();

public void EncryptFile(String SourceFilePath, String OutputFilePath)

{

// RSACryptoServiceProvider stuff.

CspParameters CSPParam = new CspParameters();

CSPParam.Flags = CspProviderFlags.NoFlags;

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(CSPParam);

rsa.ImportParameters(KeyInfo);

// Read the input file.

StreamReader sr = new StreamReader(SourceFilePath);

String FileText = sr.ReadToEnd();

sr.Close();

byte[] FileTextBytes = Unicode.GetBytes(FileText);

// Perform the encryption.

byte[] EncryptedTextBytes = rsa.Encrypt(FileTextBytes, false);

// Save it to a file.

String OutputText = Unicode.GetString(EncryptedTextBytes);

StreamWriter sw = new StreamWriter(OutputFilePath);

sw.Write(OutputText);

sw.Close();

}

public void DecryptFile(String SourceFilePath, String OutputFilePath)

{

// RSACryptoServiceProvider stuff.

CspParameters CSPParam = new CspParameters();

CSPParam.Flags = CspProviderFlags.NoFlags;

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(CSPParam);

rsa.ImportParameters(KeyInfo);

// Read the input file.

StreamReader sr = new StreamReader(SourceFilePath);

String FileText = sr.ReadToEnd();

sr.Close();

byte[] FileTextBytes = Unicode.GetBytes(FileText);

// Perform the encryption.

byte[] DecryptedTextBytes = rsa.Decrypt(FileTextBytes, false);

// Save it to a file.

String OutputText = Unicode.GetString(DecryptedTextBytes);

StreamWriter sw = new StreamWriter(OutputFilePath);

sw.Write(OutputText);

sw.Close();

}

}

}

Encryption works fine, but when I try to decrypt the encrypted file, but the decryption doesn’t work. This line

byte[] DecryptedTextBytes = rsa.Decrypt(FileTextBytes, false);

gives me a System.Security.Cryptography.CryptographicException: Bad Data.

I tried using Unicode encoding (above) and UTF8, but neither work.

Any ideas




Re: .NET Base Class Library RSACryptoServiceProvider.Decrypt() CryptographicException: "Bad Data"

jrboddie

I got your program to work with the following changes:

In the encoder:

Change: byte[] FileTextBytes = Unicode.GetBytes(FileText);

to: byte[] FileTextBytes = Encoding.UTF8.GetBytes(FileText);

and change: String OutputText = Unicode.GetString(EncryptedTextBytes);

to: String OutputText = Convert.ToBase64String(EncryptedTextBytes);

In the decoder:

Change: byte[] FileTextBytes = Unicode.GetBytes(FileText);

to: byte[] FileTextBytes = Convert.FromBase64String(FileText);

and change: String OutputText = Unicode.GetString(DecryptedTextBytes);

to: String OutputText = Encoding.UTF8.GetString(DecryptedTextBytes);

(I presume you are generating the key somewhere else in your program)





Re: .NET Base Class Library RSACryptoServiceProvider.Decrypt() CryptographicException: "Bad Data"

ubergeek2

Thanks.





Re: .NET Base Class Library RSACryptoServiceProvider.Decrypt() CryptographicException: "Bad Data"

ng1269

jrboddie,

thanks a lot. this method change my class of RijndaelManaged and they work well.

ng1269

-------------------------------------------------------------------------------------------------------

my codes are as follows:

#Region "TextEncrypt_Click"
Protected Sub TextEncrypt_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextEncrypt.Click
Dim password As String = "P0S5wD"
Dim salt As Byte() = System.Text.Encoding.ASCII.GetBytes("This is my salt")
Dim PasswordKey As Rfc2898DeriveBytes = New Rfc2898DeriveBytes(password, salt)
Dim myAlg As SymmetricAlgorithm = New RijndaelManaged()
myAlg.Key = PasswordKey.GetBytes(myAlg.KeySize / 8)
myAlg.IV = PasswordKey.GetBytes(myAlg.BlockSize / 8)
Dim encryptor As ICryptoTransform = myAlg.CreateEncryptor

' Encrypt the data as an array of encrypted bytes in memory.
Dim msEncrypt As New MemoryStream()
Dim csEncrypt As New CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)
' Convert the data to a byte array.
Dim original As String = TextBox1.Text

Dim toEncrypt As Byte() = Encoding.Unicode.GetBytes(original)

' Write all data to the crypto stream and flush it.
csEncrypt.Write(toEncrypt, 0, toEncrypt.Length)
csEncrypt.FlushFinalBlock()
' Get the encrypted array of bytes.
Dim encrypted As Byte() = msEncrypt.ToArray()

Label2.Text = Convert.ToBase64String(encrypted)
Message1.Text = "Encrypted!"
End Sub
#End Region

#Region "TextDecrypt_Click"
Protected Sub TextDecrypt_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextDecrypt.Click
Dim password As String = "P0S5wD"
Dim salt As Byte() = System.Text.Encoding.ASCII.GetBytes("This is my salt")
Dim PasswordKey As Rfc2898DeriveBytes = New Rfc2898DeriveBytes(password, salt)
Dim myAlg As SymmetricAlgorithm = New RijndaelManaged()
myAlg.Key = PasswordKey.GetBytes(myAlg.KeySize / 8)
myAlg.IV = PasswordKey.GetBytes(myAlg.BlockSize / 8)
Dim Decryptor As ICryptoTransform = myAlg.CreateDecryptor

' Convert the data to a byte array.
Dim original As String = Label2.Text
' 最大障礙是不能使用ASCII,使用Unicode才能解密
Dim toDecrypt As Byte() = Convert.FromBase64String(original)
' Now decrypt the previously encrypted message using the decryptor
' obtained in the above step.
Dim msDecrypt As New MemoryStream(toDecrypt)
Dim csDecrypt As New CryptoStream(msDecrypt, Decryptor, CryptoStreamMode.Read)
Dim fromEncrypt(toDecrypt.Length) As Byte
' Read the data out of the crypto stream.
csDecrypt.Read(fromEncrypt, 0, toDecrypt.Length)
' Convert the byte array back into a string.
Dim roundtrip As String = Encoding.Unicode.GetString(fromEncrypt)

' Display the original data and the decrypted data.
Label1.Text = roundtrip

End Sub
#End Region