C# RSA读取公钥

C# RSA读取公钥,c#,java,security,C#,Java,Security,我使用java和RSA算法生成公钥,并能够使用以下代码进行重构: X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(arrBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); publicKey = keyFactory.generatePublic(pubKeySpec); 问题 如何使用csharp在dotnet端构造公钥 示例公钥将是:,在上面的代码中,我传

我使用java和RSA算法生成公钥,并能够使用以下代码进行重构:

X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(arrBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
publicKey = keyFactory.generatePublic(pubKeySpec);
问题 如何使用csharp在dotnet端构造公钥

示例公钥将是:,在上面的代码中,我传递元素编码中包含的数据

    <sun.security.rsa.RSAPublicKeyImpl resolves-to="java.security.KeyRep">
    <type>PUBLIC</type>
    <algorithm>RSA</algorithm>
    <format>X.509</format>
    <encoded>MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMf54mcK3EYJn9tT9BhRoTX+8AkqojIyeSfog9ncYEye
0VXyBULGg2lAQsDRt8lZsvPioORZW7eB6IKawshoWUsCAwEAAQ==</encoded>
    </sun.security.rsa.RSAPublicKeyImpl>

公开的
RSA
X.509
Mfwwdqyjkozihvcnaqebqadswawsajbamf54mck3eyjn9tt9bhrotx+8AkqojIyeSfog9ncYEye
0VXYBUGGG2LAQSDRT8LZSVPIOORZW7EB6IKAWSHOWUSCAWAAQ==
不幸的是,C#没有提供任何简单的方法来实现这一点。但这将正确解码x509公钥(请确保先对x509key参数进行Base64解码):

以上代码基于(仅适用于某些键大小)。上面的代码适用于几乎任何大小的RSA密钥,并且已经用您提供的密钥以及2048位和4096位密钥进行了测试

另一种解决方案是使用工具生成证书(这是一个很好的工具),将证书导出到p12(PKCS12)文件,然后在Java和C#中加载证书以获取密钥

在C#中,可以使用
X509Certificate2
类加载PKCS12文件

X509Certificate2 cert = new X509Certificate2(certificateFile, certificatePassword, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
RSACryptoServiceProvider provider1 = (RSACryptoServiceProvider)cert.PublicKey.Key;
RSACryptoServiceProvider provider2 = (RSACryptoServiceProvider)cert.PrivateKey;
KeyStore keystore = KeyStore.getInstance("PKCS12");
keystore.load(new FileInputStream(certificateFile), certificatePassword.toCharArray());
Key key = keystore.getKey(certName, certificatePassword.toCharArray());
Certificate cert = keystore.getCertificate(certName);
PublicKey publicKey = cert.getPublicKey();
KeyPair keys = new KeyPair(publicKey, (PrivateKey) key);
在Java中,可以使用
KeyStore
类加载PKCS12文件

X509Certificate2 cert = new X509Certificate2(certificateFile, certificatePassword, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
RSACryptoServiceProvider provider1 = (RSACryptoServiceProvider)cert.PublicKey.Key;
RSACryptoServiceProvider provider2 = (RSACryptoServiceProvider)cert.PrivateKey;
KeyStore keystore = KeyStore.getInstance("PKCS12");
keystore.load(new FileInputStream(certificateFile), certificatePassword.toCharArray());
Key key = keystore.getKey(certName, certificatePassword.toCharArray());
Certificate cert = keystore.getCertificate(certName);
PublicKey publicKey = cert.getPublicKey();
KeyPair keys = new KeyPair(publicKey, (PrivateKey) key);

在Java中,将
publicKey
publicKey
转换为
RSAPublicKey

具有
getmodule
getExponent
的将获得
大整数
,从中使用
toByteArray
获取字节

我不知道Java在
biginger
类中保持前导0,所以请检查是否必须从公共指数中去掉前导null(0x00)字节

使用或将字节数组编码到基64中

您可能需要检查字节顺序(可能反转模数,不确定)

通过构造此XML来序列化它们:
{your base 64 encoded public module here}
{your base 64 encoded public index here}

在CSharp中:

var rsaCsp = new RSACryptoServiceProvider(o.BitLength);
rsaCsp.FromXmlString(xmlRsaKeyValue);
现在您有了一个加载了公钥的RSA CSP


通过添加p、Q、DP、DQ和InverseQ XML元素,可以扩展相同的过程以加载私钥。

您好,您也可以尝试这种方法

private static string[] GenerateXMLPrivatePublicKeys(){
    string[] keys = new string[2];
    RSA rsa = new RSACryptoServiceProvider(2048);
    string publicKey = rsa.ToXmlString(false);
    string privateKey = rsa.ToXmlString(true);
    keys[0] = publicKey;
    keys[1] = privateKey;
    return keys;
}

@gpa:不接受这个答案。这对你不管用吗?若有问题,你们能提供一些澄清吗?很抱歉反应太晚,但解决方案对我不起作用,因为公钥是由java生成的,并在文件中序列化。Dotnet应用程序将读取相同的公钥并构造其公钥…要生成并将公钥序列化到文件的特定Java代码是什么?(你能把它添加到你的问题中吗)Dotnet读取Java序列化对象并不容易,但是如果你将公钥保存为标准格式,那么应该可以用C#来重建它。答案更新了,添加了一些适合你的代码。在将其传递给
DecodeX509PublicKey
@gpa:Updated code之前,请确保Base64解码
arrBytes
。修复了
DecodeX509PublicKey
中的一个错误,其中指数和模数被转换为big-endian。很抱歉,我读到的所有内容都表明需要这样做(而且我显然没有进行足够彻底的测试:()),但是你在上面评论中的问题揭示了这个问题。