Управляемый BLOB-объект SIMPLEBLOB не соответствует Неуправляемому BLOB-объекту SIMPLEBLOB (RSA-криптография) - PullRequest
1 голос
/ 02 апреля 2009

Простой BLOB-объект, созданный с использованием

CryptExportKey(hKey, hPublicKey, SIMPLEBLOB, 0, lpData, &nSize);

не совпадает с кодом, сгенерированным из следующего кода (обратите внимание, что client.key - это значение ключа hKey в виде простого текста, найденное с использованием http://www.codeproject.com/KB/security/plaintextsessionkey.aspx)

CspParameters cspParams = new CspParameters();            
cspParams.KeyContainerName = "Container Name";            
cspParams.KeyNumber = (int)KeyNumber.Exchange;
cspParams.ProviderType = 1;            
cspParams.ProviderName = "Microsoft Enhanced Cryptographic Provider v1.0";            cspParams.Flags = CspProviderFlags.UseMachineKeyStore;            

RSACryptoServiceProvider rsaClient = new RSACryptoServiceProvid(cspParams);               

    rsaClient.ImportCspBlob(File.ReadAllBytes(@"C:\client.key"));//Generate a SIMPLEBLOB session key

byte[] session = GetRC4SessionBlobFromKey(keyMaterial, rsaClient);//Encrypt a key using public key and write it in a SIMPLEBLOB format


   public byte[] GetRC4SessionBlobFromKey(byte[] keyData, RSACryptoServiceProvider publicKey)        
{              
using(MemoryStream ms = new MemoryStream())              
using(BinaryWriter w = new BinaryWriter(ms))            
{                   
w.Write((byte) 0x01); // SIMPLEBLOB                    
w.Write((byte) 0x02); // Version 2                    
w.Write((byte) 0x00); // Reserved                    
w.Write(0x00006801);  // ALG_ID = RC4 for the encrypted key.                
w.Write(0x0000a400);  // CALG_RSA_KEYX                    
w.Write(publicKey.Encrypt(keyData, false));                
w.Flush();                

return ms.ToArray();              
}        
}

Почему это?

Ответы [ 2 ]

0 голосов
/ 14 апреля 2009

Я не могу отредактировать свой собственный вопрос, и поэтому я помещаю контент, который вы хотели, чтобы я прикрепил здесь, в этом ответе. У меня есть снимок экрана с изображениями из двоичного редактора / непосредственного окна в Visual Studio ниже

CryptExportKey - SIMPLEBLOB

CryptExportKey - SIMPLEBLOB http://img14.imageshack.us/img14/1926/cryptoexportkeysimplebl.jpg

Значение KeyMaterial в окне отладки

Значение ключевого материала в окне отладки http://img19.imageshack.us/img19/4138/keymaterialdebugwindow.jpg

Значение ключевого материала, которое сохраняется в файле с использованием кода проекта статьи

Ключ Значение материала, которое сохраняется в файле с использованием кода проекта статьи http://img243.imageshack.us/img243/7936/keymaterialfile.jpg

Значение ключа сеанса из GetRC4SessionBlobFromKey () (целочисленное значение отдельных байтов, разделенных запятой)

Значение ключа сеанса из GetRC4SessionBlobFromKey http://img206.imageshack.us/img206/5620/sessionvaluefromgetrc4s.jpg

Большое спасибо за внимание и, пожалуйста, дайте мне знать, если есть какая-либо дополнительная информация, которую я могу предоставить.

0 голосов
/ 05 апреля 2009
  1. Код в моем оригинальном ответе был неверным. Вы должны перевернуть зашифрованные байты. Я обновил ответ, чтобы исправить эту проблему.

  2. В приведенном выше коде отсутствует "w.Write((byte) 0x00); // Reserved". Не было ошибкой, что мой первоначальный ответ повторял эту строку.

  3. Шифрование RSA PKCS # 1 (которое используется внутри SIMPLEBLOB) не является детерминированным. И.Е. Вы не получите тот же результат, дважды зашифровав одни и те же данные.

Подводя итог: измените код выше на:

public byte[] GetRC4SessionBlobFromKey(byte[] keyData, RSACryptoServiceProvider publicKey)        
{              
  using(MemoryStream ms = new MemoryStream())              
  using(BinaryWriter w = new BinaryWriter(ms))            
  {                   
    w.Write((byte) 0x01); // SIMPLEBLOB                    
    w.Write((byte) 0x02); // Version 2                    
    w.Write((byte) 0x00); // Reserved                    
    w.Write((byte) 0x00); // Reserved                    
    w.Write(0x00006801);  // ALG_ID = RC4 for the encrypted key.                
    w.Write(0x0000a400);  // CALG_RSA_KEYX                    
    byte[] encryptedKey = publicKey.Encrypt(key.Key);
    byte[] reversedEncryptedKey = new byte[encryptedKey.Length];
    for(int i=0;i<encryptedKey.Length;i++){
      reversedEncryptedKey[i] = encryptedKey[encryptedKey.Length - 1 - i];
    }
    w.Write(reversedEncryptedKey); // encrypted key in LSB byte order

    w.Flush();                

    return ms.ToArray();              
  }        
}

и затем убедитесь, что он работает, используя CryptImportKey () для импорта SIMPLEBLOB вместо попытки сравнить результат с CryptExportKey ().

...