如何使用 RSACng 解密之前使用 RSACryptoServiceProvider 加密的数据
How to decrypt data using RSACng that is previously encrypted with RSACryptoServiceProvider
我正在从 RSACryptoServiceProvider 迁移到 RSACng 以获取新版本。但是,由于 CAPI 的 RSACryptoserviceProvider 使用 Little Endian Architecture 而 CNG API 的 RSACng 使用 Big Endian Architecture,问题是我如何使用以前的 CNG Api 解密数据使用 RSACryptoService 提供程序加密 (CAPI)?
我已经尝试 Array.reverse(cypherText) 并尝试使用 CNG Api 解密,但它抛出了错误,'The parameter is incorrect'。
- 我也尝试过解密一半密文的方法,因为 CNG API 使用 RSAEncryptionPadding.OaepSHA512 填充,而 CAPI 使用 OAEP 填充。
我的 RSACryptoServiceProvider class 如下:-
public static void EncryptWithSystemKeyRSACryptoService(byte[]
plainBytes, bool representsUnicodeString, out string cypherText)
{
CspParameters cp = new CspParameters();
cp.KeyContainerName = regValue.ToString();
cp.Flags = CspProviderFlags.UseMachineKeyStore;
cp.KeyNumber = (int)KeyNumber.Exchange;
byte[] encBlockData=null;
using (RSACryptoServiceProvider rsaCSP = new RSACryptoServiceProvider(cp))
{
res = CryptResult.GeneralError;
int keysize = rsaCSP.KeySize;
//This encrypts data and uses FOAEP padding
encBlockData = rsaCSP.Encrypt(plainBytes, true);
}
//Should i have to reverse the Byte order?
// I am doing Array.reverse for encrypted data as it follows little endian architecture and CNG Api follows Big Endian architecture
Array.Reverse(encBlockData);
cypherText = BitConverter.ToString(encBlockData );
cypherText = cypherText.Replace("-", "");
cypherText = cypherText.ToLower();
}
这就是我使用 RSACryptoservice Provider (CAPI) 加密数据的方式
我的 RSACng class 如下:-
//I am calling this to use RSACng API to get private keys
private static byte[] SetPrivateAndPublicKeysAndDecrypt(byte[] cyphertext)
{
cp.KeyContainerName = regValue.ToString();
cp.Flags = CspProviderFlags.UseMachineKeyStore;
cp.KeyNumber = (int)KeyNumber.Exchange;
using (RSACryptoServiceProvider rsaCSP = new
RSACryptoServiceProvider(cp))
{
res = CryptResult.GeneralError;
keysize = rsaCSP.KeySize;
q = rsaCSP.ExportCspBlob(false);
RSAp = rsaCSP.ExportParameters(true);
}
//created cngKey
cngKey = CngKey.Import(q, CngKeyBlobFormat.GenericPublicBlob);
//created RSACng instance
RSACng rsacng = new RSACng(cngKey)
{
KeySize = keysize
};
rsacng.ImportParameters(RSAp);
//Decrypt using RSACng API using OAEPSHA512 padding
var plainText= crypto.Decrypt(cyphertext, RSAEncryptionPadding.OaepSHA512);
return plainText;
}
预期结果应该是->明文解密成功
实际结果-> 异常被捕获-> 'The parameter is incorrect'.
RSA 密文在 PKCS#1 (which specifies PKCS#1 v1.5 RSA encryption and OAEP encryption as implemented by most libraries). The function is called I2OSP within that standard 中被定义为使用静态大小、无符号、大端编码,并且密文的大小(以完整字节计)应与密钥大小相同。如果它不是big endian,那么它不符合RSA / OAEP,换句话说。
普通的 ASN.1 编码密钥也是如此:它们根据 DER(可分辨编码规则)使用动态大小、签名的大端编码。这些密钥在 PKCS#1、PKCS#8 和 X.509 标准中定义,尽管它们也可能嵌入到 PKCS#12 兼容密钥库中 - 例如。有时,密钥也会进行 PEM 编码,以使其与需要文本而不是二进制的协议兼容。
所以你永远不必反转使用标准编码之一的密文或密钥。计算是在小端(或不是)内部执行的,这无关紧要。几乎所有现代密码或其他密码原语都是如此。输入/输出简单地以特定顺序的字节定义,而不是数字。只有非常低级别的功能可能会在例如上运行。单词,这混淆了问题(但你不会在 MS API 中找到它)。
只有 Microsoft 自己的专有(蹩脚的)密钥编码可以使用小端。
bartonjs当然是;您需要匹配填充方法,并且用于 OAEP(或者更确切地说,OAEP 中的掩码生成函数 MGF1)的默认哈希是 SHA-1。还有很多其他的陷阱需要避免,例如对明文/密文进行正确的编码/解码。
我正在从 RSACryptoServiceProvider 迁移到 RSACng 以获取新版本。但是,由于 CAPI 的 RSACryptoserviceProvider 使用 Little Endian Architecture 而 CNG API 的 RSACng 使用 Big Endian Architecture,问题是我如何使用以前的 CNG Api 解密数据使用 RSACryptoService 提供程序加密 (CAPI)?
我已经尝试 Array.reverse(cypherText) 并尝试使用 CNG Api 解密,但它抛出了错误,'The parameter is incorrect'。
- 我也尝试过解密一半密文的方法,因为 CNG API 使用 RSAEncryptionPadding.OaepSHA512 填充,而 CAPI 使用 OAEP 填充。
我的 RSACryptoServiceProvider class 如下:-
public static void EncryptWithSystemKeyRSACryptoService(byte[]
plainBytes, bool representsUnicodeString, out string cypherText)
{
CspParameters cp = new CspParameters();
cp.KeyContainerName = regValue.ToString();
cp.Flags = CspProviderFlags.UseMachineKeyStore;
cp.KeyNumber = (int)KeyNumber.Exchange;
byte[] encBlockData=null;
using (RSACryptoServiceProvider rsaCSP = new RSACryptoServiceProvider(cp))
{
res = CryptResult.GeneralError;
int keysize = rsaCSP.KeySize;
//This encrypts data and uses FOAEP padding
encBlockData = rsaCSP.Encrypt(plainBytes, true);
}
//Should i have to reverse the Byte order?
// I am doing Array.reverse for encrypted data as it follows little endian architecture and CNG Api follows Big Endian architecture
Array.Reverse(encBlockData);
cypherText = BitConverter.ToString(encBlockData );
cypherText = cypherText.Replace("-", "");
cypherText = cypherText.ToLower();
}
这就是我使用 RSACryptoservice Provider (CAPI) 加密数据的方式 我的 RSACng class 如下:-
//I am calling this to use RSACng API to get private keys
private static byte[] SetPrivateAndPublicKeysAndDecrypt(byte[] cyphertext)
{
cp.KeyContainerName = regValue.ToString();
cp.Flags = CspProviderFlags.UseMachineKeyStore;
cp.KeyNumber = (int)KeyNumber.Exchange;
using (RSACryptoServiceProvider rsaCSP = new
RSACryptoServiceProvider(cp))
{
res = CryptResult.GeneralError;
keysize = rsaCSP.KeySize;
q = rsaCSP.ExportCspBlob(false);
RSAp = rsaCSP.ExportParameters(true);
}
//created cngKey
cngKey = CngKey.Import(q, CngKeyBlobFormat.GenericPublicBlob);
//created RSACng instance
RSACng rsacng = new RSACng(cngKey)
{
KeySize = keysize
};
rsacng.ImportParameters(RSAp);
//Decrypt using RSACng API using OAEPSHA512 padding
var plainText= crypto.Decrypt(cyphertext, RSAEncryptionPadding.OaepSHA512);
return plainText;
}
预期结果应该是->明文解密成功
实际结果-> 异常被捕获-> 'The parameter is incorrect'.
RSA 密文在 PKCS#1 (which specifies PKCS#1 v1.5 RSA encryption and OAEP encryption as implemented by most libraries). The function is called I2OSP within that standard 中被定义为使用静态大小、无符号、大端编码,并且密文的大小(以完整字节计)应与密钥大小相同。如果它不是big endian,那么它不符合RSA / OAEP,换句话说。
普通的 ASN.1 编码密钥也是如此:它们根据 DER(可分辨编码规则)使用动态大小、签名的大端编码。这些密钥在 PKCS#1、PKCS#8 和 X.509 标准中定义,尽管它们也可能嵌入到 PKCS#12 兼容密钥库中 - 例如。有时,密钥也会进行 PEM 编码,以使其与需要文本而不是二进制的协议兼容。
所以你永远不必反转使用标准编码之一的密文或密钥。计算是在小端(或不是)内部执行的,这无关紧要。几乎所有现代密码或其他密码原语都是如此。输入/输出简单地以特定顺序的字节定义,而不是数字。只有非常低级别的功能可能会在例如上运行。单词,这混淆了问题(但你不会在 MS API 中找到它)。
只有 Microsoft 自己的专有(蹩脚的)密钥编码可以使用小端。
bartonjs当然是