RSA解密 - 密钥不存在

时间:2016-04-17 13:48:17

标签: c# encryption cryptography rsa

我正在尝试使用RSA加密和解密文件。加密工作正常。但是当我解密时我会收到错误。

错误是密钥不存在。

以下是错误:http://i.imgur.com/ebF09cU.png

public byte[] RSA_Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes, RSAParameters RSAKeyInfo)
{
    //initialze the byte arrays to the public key information.
    byte[] PublicKey = {214,46,220,83,160,73,40,39,201,155,19,202,3,11,191,178,56,
                           74,90,36,248,103,18,144,170,163,145,87,54,61,34,220,222,
                           207,137,149,173,14,92,120,206,222,158,28,40,24,30,16,175,
                           108,128,35,230,118,40,121,113,125,216,130,11,24,90,48,194,
                           240,105,44,76,34,57,249,228,125,80,38,9,136,29,117,207,139,
                           168,181,85,137,126,10,126,242,120,247,121,8,100,12,201,171,
                           38,226,193,180,190,117,177,87,143,242,213,11,44,180,113,93,
                           106,99,179,68,175,211,164,116,64,148,226,254,172,147};

    //Values to store encrypted symmetric keys.
    byte[] EncryptedSymmetricKey;
    byte[] EncryptedSymmetricIV;

    byte[] encryptedBytes = null;

    // Set your salt here, change it to meet your flavor:
    // The salt bytes must be at least 8 bytes.
    byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };

    using (MemoryStream ms = new MemoryStream())
    {
        using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(_stBitov))
        {
            //Set RSAKeyInfo to the public key values.
            RSAKeyInfo.Modulus = PublicKey;
            //Import key parameters into RSA.
            RSA.ImportParameters(RSAKeyInfo);

            //Create a new instance of the RijndaelManaged class.
            RijndaelManaged RM = new RijndaelManaged();

            var key = new Rfc2898DeriveBytes(PublicKey, saltBytes, 1000);

            //Encrypt the symmetric key and IV.
            EncryptedSymmetricKey = RSA.Encrypt(RM.Key, false);
            EncryptedSymmetricIV = RSA.Encrypt(RM.IV, false);

            encryptedBytes = RSA.Encrypt(bytesToBeEncrypted, false); 
        }
    }

    return encryptedBytes;
}

RSAParameters _RSAKeyInfo;

public void EncryptFile()
{
    RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();

    //Get an instance of RSAParameters from ExportParameters function.
    RSAParameters RSAKeyInfo = RSA.ExportParameters(false);
    _RSAKeyInfo = RSAKeyInfo;

    string path = ofd.FileName;

    if (File.Exists(path))
    {
        string dirPath = Path.GetDirectoryName(path);

        byte[] bytesToBeEncrypted = File.ReadAllBytes(path);

        byte[] passwordBytes = File.ReadAllBytes(dirPath + "/KEY_" + ofd.SafeFileName);

        byte[] bytesEncrypted = RSA_Encrypt(bytesToBeEncrypted, passwordBytes, RSAKeyInfo);

        string fileEncrypted = dirPath + "/ENCRYPTED_" + ofd.SafeFileName;

        File.WriteAllBytes(fileEncrypted, bytesEncrypted);
    }
}

private void button5_Click(object sender, EventArgs e)
{
    string path = ofd2.FileName;

    if (File.Exists(path))
    {
        DecryptFile();
        richTextBox4.Text = "Dekripcija uspesna";
    }
    else
    {
        richTextBox6.Text = "Datoteka ni dodana";
    }
} private void richTextBox4_TextChanged(object sender, EventArgs e) { }

public byte[] RSA_Decrypt(byte[] bytesToBeDecrypted, byte[] passwordBytes, RSAParameters RSAKeyInfo)
{
    byte[] PublicKey = {214,46,220,83,160,73,40,39,201,155,19,202,3,11,191,178,56,
                           74,90,36,248,103,18,144,170,163,145,87,54,61,34,220,222,
                           207,137,149,173,14,92,120,206,222,158,28,40,24,30,16,175,
                           108,128,35,230,118,40,121,113,125,216,130,11,24,90,48,194,
                           240,105,44,76,34,57,249,228,125,80,38,9,136,29,117,207,139,
                           168,181,85,137,126,10,126,242,120,247,121,8,100,12,201,171,
                           38,226,193,180,190,117,177,87,143,242,213,11,44,180,113,93,
                           106,99,179,68,175,211,164,116,64,148,226,254,172,147};

    //Values to store encrypted symmetric keys.
    byte[] EncryptedSymmetricKey;
    byte[] EncryptedSymmetricIV;

    byte[] decryptedBytes = null;

    // Set your salt here, change it to meet your flavor:
    // The salt bytes must be at least 8 bytes.
    byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };

    using (MemoryStream ms = new MemoryStream())
    {
        using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(_stBitov))
        {
            //Set RSAKeyInfo to the public key values.
            RSAKeyInfo.Modulus = PublicKey;
            //Import key parameters into RSA.
            RSA.ImportParameters(RSAKeyInfo);

            //Create a new instance of the RijndaelManaged class.
            RijndaelManaged RM = new RijndaelManaged();

            //Encrypt the symmetric key and IV.
            EncryptedSymmetricKey = RSA.Encrypt(RM.Key, false);
            EncryptedSymmetricIV = RSA.Encrypt(RM.IV, false);

            decryptedBytes = RSA.Decrypt(bytesToBeDecrypted, false);
        }
    }

    return decryptedBytes;
}

public void DecryptFile()
{
    string path = ofd2.FileName;

    if (File.Exists(path))
    {
        string dirPath = Path.GetDirectoryName(path);

        byte[] bytesToBeDecrypted = File.ReadAllBytes(path);

        byte[] passwordBytes = File.ReadAllBytes(dirPath + "/KEY_" + ofd.SafeFileName);

        byte[] bytesDecrypted = RSA_Decrypt(bytesToBeDecrypted, passwordBytes, _RSAKeyInfo);

        string file = dirPath + "/DECRYPTED_" + ofd.SafeFileName;

        File.WriteAllBytes(file, bytesDecrypted);
    }
}

有人可以告诉我该做什么,解密会起作用。

2 个答案:

答案 0 :(得分:1)

RSA是一种公钥加密技术。这意味着您需要一个公钥来加密消息和一个私钥来解密您的消息。看起来您正在使用公钥进行加密和解密。你的私钥在哪里?

答案 1 :(得分:1)

您似乎正在尝试使用RSA + AES执行hybrid encryption,但是您忘记实际使用AES加密明文而忘记使用RSA加密对称密钥。您还需要随机生成对称密钥,不应该从应该是常量的公钥和 public 中派生出来。

您在此处提出的错误是您遇到的问题最少,但正如ElectroByt所说,您需要使用私钥(RSACryptoServiceProvider#ExportParameters(true))来解密RSA。在您的情况下,您需要使用RSA解密以获取对称密钥以使用它来解密对称密文以获取实际消息。