【问题标题】:Decrypting the AES password in C#, which is encrptyed in Python在 C# 中解密 AES 密码,在 Python 中加密
【发布时间】:2012-02-03 10:31:53
【问题描述】:

我有一个加密密码,它是用 python 加密的。它使用带有固定密钥的 AES 128 加密的 base 64 编码结果进行加密。

现在我的应用程序是一个 C# 应用程序,我正在使用 RijndaelManaged 对其进行解密。我的代码是

static String Decrypt(string textToDecrypt, string key)
{
    RijndaelManaged rijndaelCipher = new RijndaelManaged();
    rijndaelCipher.Mode = CipherMode.CBC;
    rijndaelCipher.Padding = PaddingMode.Zeros;

    rijndaelCipher.KeySize = 0x80; //128 
    rijndaelCipher.BlockSize = 0x80; //128
    byte[] encryptedData = Convert.FromBase64String(textToDecrypt);
    byte[] pwdBytes = Encoding.UTF8.GetBytes(key);
    byte[] keyBytes = new byte[0x10]; //16
    int len = pwdBytes.Length;
    if (len > keyBytes.Length)
    {
        len = keyBytes.Length;
    }
    Array.Copy(pwdBytes, keyBytes, len);
    rijndaelCipher.Key = keyBytes;
    rijndaelCipher.IV = keyBytes;

    byte[] plainText = rijndaelCipher.CreateDecryptor().TransformFinalBlock(encryptedData, 0, encryptedData.Length);

   return Encoding.Unicode.GetString(plainText);
}

我知道密码是如何在python中加密的。就像

 key:    encryption key
    s:      string to be encrypted

    cipher            = AES.new(key, AES.MODE_CBC)
    str_to_encrypt    = _create_nonce() + _to_utf16(s)
    encrypted         = base64.b64encode(cipher.encrypt(str_to_encrypt))

_create_nonce() 根据当前时间返回一些 16 位的值。

这里的问题是我得到了前 16 个垃圾,其余的我得到了正确的结果。 可能是什么问题?我认为问题可能是 rijndaelCipher.IV。其他语言加密的rijndaelCipher.IV如何计算?

我在我的应用程序中使用 .Net 2.0,我无法更改它。 Python代码:

DEFAULT_KEY = 'SV5@9raQSV5@9raQ'
aes_encrypt(self.DEFAULT_KEY, password)

def _create_nonce():

+    t1 = time.strftime("%Y%m%d%H%M%S")
+    t2 = time.strftime("%Y%m%d%H%M%S")
+
+    return struct.pack('dd', float(t1), float(t2))
+
+
+def _to_utf16(s, max_len=32, pad='\0'):
+    
+    padded          = str.ljust(str(s), max_len, pad)
+    utf16_padded, _ = codecs.utf_16_be_encode(padded)
+    buffer          = struct.Struct(str(max_len * 2) + 'p')
+    return buffer.pack(utf16_padded)
+
+
+def aes_encrypt(key, s):

+    This will encrypt username and/or password
+    for IP Office Manager application.
+
+    Args:
+
+    key:    encryption key
+    s:      string to be encrypted
+    """
+    cipher            = AES.new(key, AES.MODE_CBC)
+    str_to_encrypt    = _create_nonce() + _to_utf16(s)
+    encrypted         = base64.b64encode(cipher.encrypt(str_to_encrypt))
+
+    return encrypted

【问题讨论】:

  • pwdBytes = Encoding.UTF8.GetBytes(key); 是错误的,很弱,很可能是您问题的一部分。
  • 您使用 AES(Rijndael 的特定子集)加密但使用 Rijndael 解密似乎很奇怪。为什么不使用 AesCryptoServiceProvider?它似乎更合适,并且不兼容的范围更小。 stackoverflow.com/a/4863924/14357
  • @Henk - 那我应该怎么做才能获得 pwdBytes?
  • @spender - 我会检查一下
  • 你也需要发布 Python 代码。

标签: c# python encryption aes


【解决方案1】:

我得到了前 16 个垃圾,其余的我得到了正确的结果。

好的,这意味着您的密码/密钥有效,但您的 IV 有问题。
您应该找出 Python 正在使用什么,因为在代码片段中看不到 IV,我猜它可能全为零。

//rijndaelCipher.IV = keyBytes;
rijndaelCipher.IV = new byte[keyBytes.Lenght];  // an array defaults to all 0x00 bytes

【讨论】:

  • 这样做,我把所有东西都当作垃圾。我已经发布了python代码,你能看看吗
  • @Sunil 听起来难以置信。在 CBC 模式下更改 IV 解密不会影响任何后续块。
  • 您能否编译代码并在此处告诉我问题。加密值:"wDkvBlzgoRCz749u3OjL8/uXXc4CfdEgqP7lk3okP104HxAxQaadVdCWgzE4uUNO9B+RYnstFmDf21CSZ89GxnzBJtiirXi0N+/IIocPjwg="解密值必须是:16位Nonce值+"管理员"+\0\0...
  • @Ben IV 的选择只影响加密期间的所有块,但不影响解密期间。每个块只依赖于前一个块的密文。所以选择错误的IV进行解密只会影响第一个块。
  • @CodeInChaos,在 CBC 模式下,IV 会影响所有块。见en.wikipedia.org/wiki/…。同样,对第一个块使用 nonce 或多或少等同于使用 IV - 第一个块密文是第二个块的 IV。
【解决方案2】:

我修复了 base64 中的无效字符。

  • 工作正常

       string textToDecrypt = 
            "wDkvBlzgoRCz749u3OjL8/uXXc4CfdEg"
          + "qP7lk3okP104HxAxQaadVdCWgzE4uUNO"
          + "9B+RYnstFmDf21CSZ89GxnzBJtiirXi0"
          + "N+/IIocPjwg=";
    

你加密的是随机数+密码。你得到的是随机数+密码。

您抱怨的前 16 个字节的废话是随机数。把它们扔掉。

编辑:

正如@CodeInChaos 指出的那样,在 CBC 模式下,如果你弄错了 IV,第一个块将无法正确解密,但后续块会正确解密。但是,在您的情况下,第一个块是加密的 nonce,并且您不在乎是否将 nonce 取回,因为无论如何您都会将其丢弃。因此,解密时 IV 使用什么并不重要。

【讨论】:

  • 其实我也关心NOnce。我也需要那个值:(。无论如何谢谢你的帮助。
【解决方案3】:

从你的问题我看到你是这么说的:

当 rijndaelCipher.IV 以其他方式加密时,我们如何计算它 语言?

AES 是一种对称密码。如果没有 KEYIV,您将无法(不尝试蛮力)解密您的密码。

因此,根据您上面的报价,您并且不应该计算要解密的 IV。您必须使用加密时使用的 IV。

您必须找出用于 IV 的 phyton 代码。

【讨论】:

  • 我已经发布了用于加密的python代码。如何找到它?
  • 也许您需要了解更多有关正在使用的 AES 库的信息。您的代码仅显示cipher = AES.new(key, AES.MODE_CBC)。我建议了解更多关于 AES 课程的信息。可能是它使用了一个全零的 IV,这是不安全的。
  • @Adam an all 0 IV 是他的问题中最少的。假设它确实是唯一的,随机数在一定程度上减轻了 IV 的缺失(如果多个字符串被快速连续加密,则可能不是这样)。
  • 投反对票没有评论? 不要做一个匿名的懦夫。 事实上@Sunil 需要加密时使用的 IV 才能解密。无论是生成的 IV 还是静态 IV(包括全零
  • @AdamSpicer,这是我的反对意见,Sunil 不需要 IV 来解密,因为它是 CBC 模式,他不需要第一个块。
猜你喜欢
  • 2020-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-14
  • 2015-07-06
  • 1970-01-01
  • 2019-11-04
  • 2019-10-27
相关资源
最近更新 更多