Расшифровка пароля AES в C #, который зашифрован в Python - PullRequest
0 голосов
/ 03 февраля 2012

У меня есть зашифрованный пароль, который зашифрован на 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

Ответы [ 3 ]

2 голосов
/ 03 февраля 2012

Я исправил недопустимые символы в base64.

  • Он работает правильно

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

То, что вы зашифровали, было nonce + password.То, что вы получаете, это nonce + password.

Первые 16 байтов ерунды, на которые вы жалуетесь , являются nonce .Просто выбросьте их.

Редактировать:

Как указывало @CodeInChaos, в режиме CBC, если вы ошибетесь с IV, первый блок не будет правильно расшифрован,хотя последующие блоки будут.Однако в вашем случае первый блок - это зашифрованный одноразовый номер , и вам все равно, вернете ли вы одноразовый номер или нет, так как вы все равно его выбросите.Поэтому не имеет значения, что вы используете для IV при расшифровке.

2 голосов
/ 03 февраля 2012

Я получаю первые 16 как мусор, а остальные я получаю правильно.

ОК, это означает, что ваш пароль / ключ работает, но у вас есть проблема с IV.
Вы должны выяснить, что использует Python, поскольку во фрагменте кода не видно IV, я думаю, это могут быть все нули.

//rijndaelCipher.IV = keyBytes;
rijndaelCipher.IV = new byte[keyBytes.Lenght];  // an array defaults to all 0x00 bytes
0 голосов
/ 03 февраля 2012

По твоему вопросу я увидел, что ты сказал это:

Как рассчитать rijndaelCipher.IV, когда он зашифрован в другом язык

AES - симметричный шифр. Вы не можете (без попытки перебора) расшифровать свой шифр БЕЗ КЛЮЧ и IV .

Итак, исходя из приведенной выше цитаты, вы не и не должны вычислять IV для расшифровки. Вы должны использовать IV, который использовался, когда он был зашифрован.

Вы должны выяснить, какой фитонный код используется для IV.

...