【问题标题】:System.Security.Cryptography.CryptographicException when wrong password given输入错误密码时出现 System.Security.Cryptography.CryptographicException
【发布时间】:2014-10-11 03:49:23
【问题描述】:

我的代码在密码的帮助下为我加密和解密字符串。

当我输入错误的密码时,我收到此错误:

在 mscorlib.dll 中发生了“System.Security.Cryptography.CryptographicException”类型的未处理异常

这是我的加密类代码:

using System;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace EncryptStringSample
{
public static class StringCipher
{
    // This constant string is used as a "salt" value for the PasswordDeriveBytes     function calls.
    // This size of the IV (in bytes) must = (keysize / 8).  Default keysize is 256, so     the IV must be
    // 32 bytes long.  Using a 16 character string here gives us 32 bytes when converted to a byte array.
    private const string initVector = "tu89geji340t89u2";

    // This constant is used to determine the keysize of the encryption algorithm.
    private const int keysize = 256;

    public static string Encrypt(string plainText, string passPhrase)
    {
        byte[] initVectorBytes = Encoding.UTF8.GetBytes(initVector);
        byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
        PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null);
        byte[] keyBytes = password.GetBytes(keysize / 8);
        RijndaelManaged symmetricKey = new RijndaelManaged();
        symmetricKey.Mode = CipherMode.CBC;
        ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes);
        MemoryStream memoryStream = new MemoryStream();
        CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write);
        cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
        cryptoStream.FlushFinalBlock();
        byte[] cipherTextBytes = memoryStream.ToArray();
        memoryStream.Close();
        cryptoStream.Close();
        return Convert.ToBase64String(cipherTextBytes);
    }

    public static string Decrypt(string cipherText, string passPhrase)
    {
        byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector);
        byte[] cipherTextBytes = Convert.FromBase64String(cipherText);
        PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null);
        byte[] keyBytes = password.GetBytes(keysize / 8);
        RijndaelManaged symmetricKey = new RijndaelManaged();
        symmetricKey.Mode = CipherMode.CBC;
        ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes);
        MemoryStream memoryStream = new MemoryStream(cipherTextBytes);
        CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);
        byte[] plainTextBytes = new byte[cipherTextBytes.Length];
        int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
        memoryStream.Close();
        cryptoStream.Close();
        return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
    }
  }
}

错误发生在这里:

int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);

我把这里的一切都称为:

// encrypting the raw text using PrivateKey
text_encrypted = EncryptStringSample.StringCipher.Encrypt(text_raw, PrivateKey);

// decrypting encrypted message using Partners Private Key
string text_decrypted = EncryptStringSample.StringCipher.Decrypt(decrypt_me, partner_PrivateKey);

是什么导致了这个异常,应该如何处理?

【问题讨论】:

  • 一些可能会帮助您获得答案的事情:您在哪里调用您的代码?是加密还是解密中的错误?你传递给方法的参数是什么?如有疑问,您可以包含错误堆栈跟踪。事实上,您提供的信息不足以找到您的问题。另外,请查看 C# using 语句:您应该将它用于您的 Streams。
  • 您好,我在解密时遇到了问题。这是代码: string text_decrypted = EncryptStringSample.StringCipher.Decrypt(decrypt_me, partner_PrivateKey);
  • 一些注意事项: 1) 你不能依赖得到这个错误。尽管在 256 次测试中约有 1 次密码错误,但我预计不会出错。 2)你的代码很烂。没有盐或 IV(=> 多目标攻击),不正确的 cmets(密钥大小和 IV 大小不相关,使用 UTF-8 编码时 16 个 ASCII 字符产生 16 个字节,而不是 32 个字节),可能截断明文(Stream.Read 可能返回少于请求的字节数)并且没有 MAC(=> 填充预言或类似攻击)。

标签: c# cryptography


【解决方案1】:

使用无效密码时应该会出现 CryptographicException。

您的代码在提供正确密码时工作正常,因此只需捕获异常并做出正确反应(向最终用户显示消息或其他内容)。

或者你可以添加

symmetricKey.Padding = PaddingMode.Zeros;

解密后,您应该删除八个表明解密成功的\0 值。

【讨论】:

    猜你喜欢
    • 2011-09-27
    • 1970-01-01
    • 1970-01-01
    • 2017-02-26
    • 2018-03-11
    • 1970-01-01
    • 1970-01-01
    • 2013-03-13
    • 2022-01-05
    相关资源
    最近更新 更多