c#等价于“java.security.spec.RSAPublicKeySpec”和“java.security.PublicKey”

时间:2013-04-15 18:17:31

标签: c# java encryption rsa

我正在使用现有java应用程序的c#开发新版本。

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

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

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

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

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

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

关于你的问题,here是在纯Bouncy Castle中实现签名的一个例子,它处理MakeKey方法中的密钥生成,所以你可能想看看它。

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

修改

我尝试将你的方法转换为c#等价物,这就越接近我了:

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

答案 1 :(得分: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;
}