1

我正在用 C# 开发现有 Java 应用程序的新版本。

现有应用程序使用带有 java.security.spec.* 和 boncycastle api 的 RSA 加密。

我正在为下面的 java 代码寻找 c# 中的等效代码:

public static java.security.PublicKey getKey
(
org.bouncycastle.asn1.x509.RSAPublicKeyStructure  rsaPublicKey
)
{

java.security.KeyFactory keyFactory = KeyFactory.getInstance("RSA");

 java.security.spec.RSAPublicKeySpec keySpec = new RSAPublicKeySpec(
rsaPublicKey.getModulus(), 
rsaPublicKey.getPublicExponent());

java.security.PublicKey pkey = keyFactory.generatePublic(keySpec);

return pkey;
}

我“搜索”了很多,但没有找到解决方案。

在此先感谢您的帮助。

4

2 回答 2

2

尽管您可能已经意识到这一点,但有一个 .NET 版本的Bouncy Castle,因此您可以在您的 C# 项目中使用它。

关于您的问题,这里是在纯 Bouncy Castle 中实现签名的示例,它处理 MakeKey 方法中的密钥生成,因此您可能想看看它。

顺便说一句,如果此密钥在证书中,您可能需要查看 .NET X509Certificate2 类。

编辑

我试图将您的方法转换为 ac# 等价物,我越接近它:

public static byte[] getKey(Org.BouncyCastle.Asn1.x509.RSAPublicKeyStructure  rsaPublicKey)
{
    Org.BouncyCastle.Crypto.Parameters.RsaKeyParameters bcKeySpec = new RsaKeyParameters();
    bcKeySpec.RsaKeyParameters(false, rsaPublicKey.getModulus(), rsaPublicKey.getPublicExponent());
    RSAParameters keySpec = Org.BouncyCastle.Security.DotNetUtilities.ToRSAParameters(bcKeySpec);
    RSACryptoServiceProvider keyFactory = new RSACryptoServiceProvider();
    keyFactory.ImportParameters(keySpec);
    byte[] pKey = keyFactory.ExportCspBlob(false);
    return pKey;
}

请注意,密钥被导出到一个字节数组中,这取决于您以后要对密钥做什么,可能对您有帮助也可能对您没有帮助,此外,RSACryptoServiceProvider 对象允许您加密、解密、签名和验证,所以如果您将获得用于任何这些目的的密钥,那么您可能希望返回 keyFactory 对象而不是导出的公钥。

如果您想了解有关 RSACryptoServiceProvider 的更多信息,可以在此处阅读:http: //msdn.microsoft.com/en-us/library/s575f7e2.aspx

于 2013-04-15T19:44:49.490 回答
0
 public static string EncryptRsa(string stringPublicKey, string stringDataToEncrypt)
{
    byte[] publicKey = Convert.FromBase64String(stringPublicKey);
    using (RSACryptoServiceProvider rsa = DecodeX509PublicKey(publicKey))
    {
        byte[] dataToEncrypt = Encoding.UTF8.GetBytes(stringDataToEncrypt);
        byte[] encryptedData = rsa.Encrypt(dataToEncrypt, false);
        return Convert.ToBase64String(encryptedData);
    }
}

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(1024);
                    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;
}
于 2018-10-04T02:35:52.917 回答