我从Java生成以下公钥作为RSA:
305c300d06092a864886f70d0101010500034b003048024100ab12b3ee64b85bdda7e9744df3210d9b0efc7fbd36385cd903a4f8ee51101bc9c4f0b23583ff090e7d61773e024cbbff4008037cba6538d1c70d865c948716e70203010001
我尝试按以下方式导入密钥:
1)将字符串解码为字节数组(键)
public static byte[] DecodeKey(string data)
{
int count = data.Length;
byte[] key = new byte[count / 2];
for (int i = 0; i < count ; i += 2)
key[i / 2] = Convert.ToByte(data.Substring(i, 2), 16);
return key;
}
2)CryptAcquireContext
使用Microsoft Strong Cryptographic Provider
和PROV_RSA_FULL
3)然后使用上面的密钥和CryptImportKey
拨打key.Length
。
它返回:
提供商的错误版本。
答案 0 :(得分:1)
您的RSA密钥采用SubjectPublicKeyInfo
格式,这是Java在您使用RSAPublicKey.getEncoded()
方法时返回的格式。由于历史原因,Java将此格式称为X509EncodeKeySpec
。
这是.NET的一种不方便的格式。您可以检查.NET类以查看哪种格式最方便。我怀疑最方便的格式是XML格式。以下Java代码段将以此格式输出RSA公钥:
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.interfaces.RSAPublicKey;
import javax.xml.bind.DatatypeConverter;
public class RSAToXML {
public static void main(String[] args) throws Exception {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(1024);
KeyPair keyPair = kpg.generateKeyPair();
RSAPublicKey rsaPub = (RSAPublicKey) keyPair.getPublic();
System.out.println("<RSAKeyValue>");
System.out.print("\t<Modulus>");
System.out.print(DatatypeConverter.printBase64Binary(rsaPub.getModulus().toByteArray()));
System.out.println("</Modulus>");
System.out.print("\t<Exponent>");
System.out.print(DatatypeConverter.printBase64Binary(rsaPub.getPublicExponent().toByteArray()));
System.out.println("</Exponent>");
System.out.println("</RSAKeyValue>");
}
}
然后可以使用此输出将RSA公钥导入.NET,如下面的C#片段所示:
public static void XmlImport()
{
var xmlPubKey = "<RSAKeyValue>\n\t<Modulus>AI0hSZ3hcfJHv1TPSIkT0XeW/HMPPFJMw4/aX5NxfhyVacpb5u6rucDztVNG1pXaBdya9OdO1+mGG250y+QuqP/70uu5QMcMEpCdp8xl0i+cUN9+fHDzse4XR/Kdrl3pKAefSR5QQX8xBScjTO+H+9fXVrrU9TQU6WXmahQnDwDJ</Modulus>\n\t<Exponent>AQAB</Exponent>\n</RSAKeyValue>\n";
var rsa = RSA.Create();
rsa.FromXmlString(xmlPubKey);
Console.WriteLine(rsa.ToXmlString(false));
}
注意:这使用.NET类,而不是Win32 CryptoAPI。几乎没有理由继续使用CryptoAPI。