为什么错误的密码导致“填充无效并且不能被删除”? [英] Why does a bad password cause "Padding is invalid and cannot be removed"?

查看:212
本文介绍了为什么错误的密码导致“填充无效并且不能被删除”?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一些简单的字符串加密,所以我写了以下代码(来自 here ):

  //创建并初始化加密算法
private static对称算法getAlgorithm(string password){
SymmetricAlgorithm algorithm = Rijndael.Create();
Rfc2898DeriveBytes rdb = new Rfc2898DeriveBytes(
password,new byte [] {
0x53,0x6f,0x64,0x69,0x75,0x6d,0x20,// salty goodness
0x43,0x68 ,0x6c,0x6f,0x72,0x69,0x64,0x65
}
);
algorithm.Padding = PaddingMode.ISO10126;
algorithm.Key = rdb.GetBytes(32);
algorithm.IV = rdb.GetBytes(16);
返回算法;
}

/ *
* encryptString
*提供一个字符串的简单加密,给定的密码
* /
public static string encryptString(string clearText,string password){
SymmetricAlgorithm algorithm = getAlgorithm(password);
byte [] clearBytes = System.Text.Encoding.Unicode.GetBytes(clearText);
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms,algorithm.CreateEncryptor(),CryptoStreamMode.Write);
cs.Write(clearBytes,0,clearBytes.Length);
cs.Close();
return Convert.ToBase64String(ms.ToArray());
}

/ *
* decryptString
*提供一个字符串的简单解密,给定的密码
* /
public static string decryptString(string cipherText,string password){
SymmetricAlgorithm algorithm = getAlgorithm(password);
byte [] cipherBytes = Convert.FromBase64String(cipherText);
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms,algorithm.CreateDecryptor(),CryptoStreamMode.Write);
cs.Write(cipherBytes,0,cipherBytes.Length);
cs.Close();
return System.Text.Encoding.Unicode.GetString(ms.ToArray());
}

该代码似乎工作正常,但是使用不正确的密钥解密数据时除外,我得到一个CryptographicException - 填充无效,不能被删除 - 在csClose()行在decryptString。



示例代码:

  string password1 =password 
string password2 =letmein;
string startClearText =快速的棕色狐狸跳过懒狗;
string cipherText = encryptString(startClearText,password1);
string endClearText = decryptString(cipherText,password2); //抛出异常

我的问题是,这是预期的吗?我会以为使用错误的密码解密只会导致废话输出,而不是异常。

解决方案

虽然这有已经回答了我认为这是一个好主意,解释为什么是预期的。



通常应用填充方案,因为大多数加密过滤器在语义上不安全,并且防止某些形式的密码。例如,通常在RSA中,使用 OAEP 填充方案来防止某些类型的攻击(例如选择的明文攻击或致盲)。



填充方案在消息发送之前将一些(通常)随机垃圾附加到消息m。例如,在OAEP方法中,使用两个Oracles(这是一个简单的解释):


  1. 给定你的模数的大小k1位为0,k0位为随机数。

  2. 然后通过对消息进行一些转换,获得加密和发送的填充消息。

这为您提供了一个随机化的消息,并以一种方式来测试消息是否是垃圾。由于填充方案是可逆的,当您解密消息时,您不能对消息本身的完整性进行任何说明,实际上,您可以对填充进行一些断言,因此您可以知道消息是否已被正确解密或者你做错了(即有人篡改了消息,或者你使用错误的密钥)


I needed some simple string encryption, so I wrote the following code (with a great deal of "inspiration" from here):

    // create and initialize a crypto algorithm
    private static SymmetricAlgorithm getAlgorithm(string password) {
        SymmetricAlgorithm algorithm = Rijndael.Create();
        Rfc2898DeriveBytes rdb = new Rfc2898DeriveBytes(
            password, new byte[] {
            0x53,0x6f,0x64,0x69,0x75,0x6d,0x20,             // salty goodness
            0x43,0x68,0x6c,0x6f,0x72,0x69,0x64,0x65
        }
        );
        algorithm.Padding = PaddingMode.ISO10126;
        algorithm.Key = rdb.GetBytes(32);
        algorithm.IV = rdb.GetBytes(16);
        return algorithm;
    }

    /* 
     * encryptString
     * provides simple encryption of a string, with a given password
     */
    public static string encryptString(string clearText, string password) {
        SymmetricAlgorithm algorithm = getAlgorithm(password);
        byte[] clearBytes = System.Text.Encoding.Unicode.GetBytes(clearText);
        MemoryStream ms = new MemoryStream();
        CryptoStream cs = new CryptoStream(ms, algorithm.CreateEncryptor(), CryptoStreamMode.Write);
        cs.Write(clearBytes, 0, clearBytes.Length);
        cs.Close();
        return Convert.ToBase64String(ms.ToArray());
    }

    /*
     * decryptString
     * provides simple decryption of a string, with a given password
     */
    public static string decryptString(string cipherText, string password) {
        SymmetricAlgorithm algorithm = getAlgorithm(password);
        byte[] cipherBytes = Convert.FromBase64String(cipherText);
        MemoryStream ms = new MemoryStream();
        CryptoStream cs = new CryptoStream(ms, algorithm.CreateDecryptor(), CryptoStreamMode.Write);
        cs.Write(cipherBytes, 0, cipherBytes.Length);
        cs.Close();            
        return System.Text.Encoding.Unicode.GetString(ms.ToArray());
    }

The code appears to work fine, except that when decrypting data with an incorrect key, I get a CryptographicException - "Padding is invalid and cannot be removed" - on the cs.Close() line in decryptString.

example code:

    string password1 = "password";
    string password2 = "letmein";
    string startClearText = "The quick brown fox jumps over the lazy dog";
    string cipherText = encryptString(startClearText, password1);
    string endClearText = decryptString(cipherText, password2);     // exception thrown

My question is, is this to be expected? I would have thought that decrypting with the wrong password would just result in nonsense output, rather than an exception.

解决方案

Although this have been already answered I think it would be a good idea to explain why it is to be expected.

A padding scheme is usually applied because most cryptographic filters are not semantically secure and to prevent some forms of cryptoatacks. For example, usually in RSA the OAEP padding scheme is used which prevents some sorts of attacks (such as a chosen plaintext attack or blinding).

A padding scheme appends some (usually) random garbage to the message m before the message is sent. In the OAEP method, for example, two Oracles are used (this is a simplistic explanation):

  1. Given the size of the modulus you padd k1 bits with 0 and k0 bits with a random number.
  2. Then by applying some transformation to the message you obtain the padded message wich is encrypted and sent.

That provides you with a randomization for the messages and with a way to test if the message is garbage or not. As the padding scheme is reversible, when you decrypt the message whereas you can't say anything about the integrity of the message itself you can, in fact, make some assertion about the padding and thus you can know if the message has been correctly decrypted or you're doing something wrong (i.e someone has tampered with the message or you're using the wrong key)

这篇关于为什么错误的密码导致“填充无效并且不能被删除”?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆