托管的SIMPLEBLOB blob与Unmanaged SIMPLEBLOB(RSA -Cryptography)不匹配

时间:2009-04-01 23:52:29

标签: c# cryptography rsa

使用

生成的简单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();              
}        
}

为什么?

2 个答案:

答案 0 :(得分:0)

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

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

  3. RSA PKCS#1加密(在SIMPLEBLOB中使用)不具有确定性。 I.E.通过两次加密相同的数据,您将得不到相同的结果。

  4. 总而言之:将上面的代码更改为:

    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()进行比较。

答案 1 :(得分:0)

我无法编辑自己的问题因此我在这个答案中放置了您希望我附加的内容,我在下面的visual studio中的二进制编辑器/即时窗口中截取了图像的屏幕截图

CryptExportKey - SIMPLEBLOB

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

调试窗口中的KeyMaterial值

Key Material value in debug window http://img19.imageshack.us/img19/4138/keymaterialdebugwindow.jpg

使用代码项目文章

保存在文件中的密钥材料值

Key Material value that is saved in file using the code project article http://img243.imageshack.us/img243/7936/keymaterialfile.jpg

GetRC4SessionBlobFromKey()的会话密钥值(以逗号分隔的单个字节的整数值)

Session key value from GetRC4SessionBlobFromKey http://img206.imageshack.us/img206/5620/sessionvaluefromgetrc4s.jpg

非常感谢您对此进行调查,如果我能提供更多信息,请与我们联系。