c# equivalent of “java.security.spec.RSAPublicKeySpec” and “java.security.PublicKey”

北城以北 提交于 2021-02-08 08:48:21

问题


I'm developing a new version in c# of an existing java application.

The existing application uses RSA encryption with java.security.spec.* and boncycastle api.

I'm looking for equivalent code in c# for the java below code:

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

I "googled" a lot but don't found solution.

Thanks in advance for your help.


回答1:


Although you may be already aware of this, there is a .NET version of Bouncy Castle, so you can use it in your C# project.

Regarding your question, here is an example of implementing signing in pure Bouncy Castle, an it deals with key generation in the MakeKey method, so you may want to take a look at it.

By the way, if this key is in a certificate, you may want to look at the .NET X509Certificate2 class.

Edit

I tried to convert your method into a c# equivalent, and this it the closer I got:

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

Note that the key is exported into a byte array, which depending of what you want to do with your key later, may or may not be helpful to you, also, the RSACryptoServiceProvider object let you encrypt, decrypt, sign and verify, so if you are going to get the key for any of these purposes, then you may want to return the keyFactory object instead of the exported public key.

If you want more information about RSACryptoServiceProvider you can read here: http://msdn.microsoft.com/en-us/library/s575f7e2.aspx




回答2:


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


来源:https://stackoverflow.com/questions/16022062/c-sharp-equivalent-of-java-security-spec-rsapublickeyspec-and-java-security-p

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!