1

使用生成的简单 blob

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

与以下代码生成的不匹配(请注意,client.key 是使用http://www.codeproject.com/KB/security/plaintextsessionkey.aspx找到的 hKey 的纯文本键值)

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();              
}        
}

这是为什么?

4

2 回答 2

0
  1. 原始答案中的代码不正确。您必须反转加密的字节。我已经更新了解决该问题的答案。

  2. 上面的代码缺少一个“ w.Write((byte) 0x00); // Reserved”。我最初的答案重复了那句话并不是一个错误。

  3. RSA PKCS#1 加密(在 SIMPLLEBLOB 中使用)不是确定性的。IE 两次加密相同的数据不会得到相同的结果。

所以总结一下:将上面的代码更改为:

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() 进行比较来检查它是否有效。

于 2009-04-05T14:59:01.460 回答
0

我无法编辑自己的问题,因此我将您希望我在此答案中附加的内容放在这里,我从下面的 Visual Studio 中的二进制编辑器/立即窗口中截取了图像

CryptExportKey - SIMPLEBLOB

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

调试窗口中的 KeyMaterial 值

调试窗口中的关键材料值 http://img19.imageshack.us/img19/4138/keymaterialdebugwindow.jpg

使用代码项目文章保存在文件中的 Key Material 值

使用代码项目文章 http://img243.imageshack.us/img243/7936/keymaterialfile.jpg 保存在文件中的 Key Material 值

来自 GetRC4SessionBlobFromKey() 的会话键值(由逗号分隔的单个字节的整数值)

来自 GetRC4SessionBlobFromKey 的会话键值 http://img206.imageshack.us/img206/5620/sessionvaluefromgetrc4s.jpg

非常感谢您对此进行调查,如果我可以提供任何进一步的信息,请告诉我。

于 2009-04-14T10:12:42.997 回答