我的任务是使用CryptoApi替换一些旧的旧代码,而CryptoApi已被弃用,并使用更新的Cryptography API:Windows的下一代。新的加密方法必须产生与旧的相同的结果。
我简化了旧方法以使其更紧凑(您可以将其视为伪代码):
private UIntPtr mProviderHandle = UIntPtr.Zero;
private UIntPtr mHashHandle = UIntPtr.Zero;
private UIntPtr mKeyHandle = UIntPtr.Zero;
private uint mBlockSize = 0;
private bool m_disposed;
private void Init(string pContextName, string pSharedSecret)
{
string providerName = = "Microsoft Base Cryptographic Provider v1.0";
var providerType = ProviderType.PROV_RSA_FULL; // 1
var providerFlags = ContextOperations.CRYPT_DEFAULT; // 0
var hashAlg = ProviderAlgorithm.CALG_MD5; // 0x8003
var keyAlg = ProviderAlgorithm.CALG_RC2; // 0x6602
CryptAcquireContext(ref mProviderHandle, pContextName, providerName, providerType, providerFlags);
CryptCreateHash(mProviderHandle, hashAlg, UIntPtr.Zero, 0, ref mHashHandle);
CryptHashData(mHashHandle, Encoding.Default.GetBytes(pSharedSecret), (uint)pSharedSecret.Length, 0))
CryptDeriveKey(mProviderHandle, keyAlg, mHashHandle, 0, ref mKeyHandle));
}
public byte[] Encrypt(byte[] pData, bool pFinal = true)
{
uint length = (uint)bytes.Length;
uint m = 0;
if (0 < BlockSize)
{
// one more blocks than the number of blocks touched
m = (uint)(((((length - 1) / BlockSize) + 1) + 1) * BlockSize);
Array.Resize(ref bytes, (int)m);
}
else
{
m = length;
}
APIBOOL apiFinal = pFinal ? APIBOOL.TRUE : APIBOOL.FALSE;
if (APIBOOL.FALSE != NativeMethods.CryptEncrypt(mKeyHandle, UIntPtr.Zero, apiFinal, 0,
bytes, ref length, m))
{
Array.Resize(ref bytes, (int)length);
encrypted = true;
}
return bytes;
}
这是新方法:
private byte[] EncryptCNG(byte[] data, string pSharedSecret)
{
using (RC2CryptoServiceProvider rc2 = new RC2CryptoServiceProvider())
{
using (MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider())
{
rc2.Key = md5.ComputeHash(Encoding.Unicode.GetBytes(pSharedSecret));
rc2.IV = new byte[rc2.BlockSize/8];
}
var encryptor = rc2.CreateEncryptor();
var result = encryptor.TransformFinalBlock(data, 0, data.Length);
return result;
}
}
两个方法Encrypt()和EncryptCNG()都产生一个具有相同长度和恒定值(取决于输入)的字节数组。但是值/字节不同。所需的结果是相同的输入生成相同的输出。这样Encrypt可以被EncryptCNG取代。 我的问题是,EncryptCNG是否是使用新API的正确方法,以及它是否是Init + Encrypt功能的正确翻译?如果是的话,为什么会产生不同的结果?
非常感谢您的帮助。