gpt4 book ai didi

c# - RSA 读取公钥

转载 作者:搜寻专家 更新时间:2023-10-31 08:12:13 24 4
gpt4 key购买 nike

我有使用 java 和 RSA 算法生成的公钥,并且能够使用以下代码重建:

X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(arrBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
publicKey = keyFactory.generatePublic(pubKeySpec);

问题如何使用 csharp 在 dotnet 端构造 PublicKey?

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

中的数据
    <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>

最佳答案

不幸的是,C# 没有提供任何简单的方法来执行此操作。但这将正确解码 x509 公钥(请确保首先对 x509key 参数进行 Base64 解码):

public static RSACryptoServiceProvider DecodeX509PublicKey(byte[] x509key)
{
byte[] SeqOID = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 };

MemoryStream ms = new MemoryStream(x509key);
BinaryReader reader = new BinaryReader(ms);

if (reader.ReadByte() == 0x30)
ReadASNLength(reader); //skip the size
else
return null;

int identifierSize = 0; //total length of Object Identifier section
if (reader.ReadByte() == 0x30)
identifierSize = ReadASNLength(reader);
else
return null;

if (reader.ReadByte() == 0x06) //is the next element an object identifier?
{
int oidLength = ReadASNLength(reader);
byte[] oidBytes = new byte[oidLength];
reader.Read(oidBytes, 0, oidBytes.Length);
if (oidBytes.SequenceEqual(SeqOID) == false) //is the object identifier rsaEncryption PKCS#1?
return null;

int remainingBytes = identifierSize - 2 - oidBytes.Length;
reader.ReadBytes(remainingBytes);
}

if (reader.ReadByte() == 0x03) //is the next element a bit string?
{
ReadASNLength(reader); //skip the size
reader.ReadByte(); //skip unused bits indicator
if (reader.ReadByte() == 0x30)
{
ReadASNLength(reader); //skip the size
if (reader.ReadByte() == 0x02) //is it an integer?
{
int modulusSize = ReadASNLength(reader);
byte[] modulus = new byte[modulusSize];
reader.Read(modulus, 0, modulus.Length);
if (modulus[0] == 0x00) //strip off the first byte if it's 0
{
byte[] tempModulus = new byte[modulus.Length - 1];
Array.Copy(modulus, 1, tempModulus, 0, modulus.Length - 1);
modulus = tempModulus;
}

if (reader.ReadByte() == 0x02) //is it an integer?
{
int exponentSize = ReadASNLength(reader);
byte[] exponent = new byte[exponentSize];
reader.Read(exponent, 0, exponent.Length);

RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
RSAParameters RSAKeyInfo = new RSAParameters();
RSAKeyInfo.Modulus = modulus;
RSAKeyInfo.Exponent = exponent;
RSA.ImportParameters(RSAKeyInfo);
return RSA;
}
}
}
}
return null;
}

public static int ReadASNLength(BinaryReader reader)
{
//Note: this method only reads lengths up to 4 bytes long as
//this is satisfactory for the majority of situations.
int length = reader.ReadByte();
if ((length & 0x00000080) == 0x00000080) //is the length greater than 1 byte
{
int count = length & 0x0000000f;
byte[] lengthBytes = new byte[4];
reader.Read(lengthBytes, 4 - count, count);
Array.Reverse(lengthBytes); //
length = BitConverter.ToInt32(lengthBytes, 0);
}
return length;
}

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

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

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

X509Certificate2 cert = new X509Certificate2(certificateFile, certificatePassword, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
RSACryptoServiceProvider provider1 = (RSACryptoServiceProvider)cert.PublicKey.Key;
RSACryptoServiceProvider provider2 = (RSACryptoServiceProvider)cert.PrivateKey;

在 Java 中,您可以使用 KeyStore 类加载 PKCS12 文件。

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);

关于c# - RSA 读取公钥,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18091460/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com