Convert Java.Security.KeyPair to .NET RSACryptoServiceProvider

后端 未结 2 783
深忆病人
深忆病人 2021-01-16 02:12

How can I encode a Java-produced RSA private (and public) key such that it can be decoded in .NET for use within RSACryptoServiceProvider?

I have tried

相关标签:
2条回答
  • 2021-01-16 02:55

    C# has a load from xml functionm for RSA Crypto Provider. Try the approach below:

    JAVA

                    KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(1024);
        KeyPair keyPair = keyGen.generateKeyPair();
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        BigInteger mod_Int = publicKey.getModulus();
        BigInteger exp_Int = publicKey.getPublicExponent();
        byte[] mod_Bytes_Extra = mod_Int.toByteArray();
        byte[] mod_Bytes = new byte[128];
        System.arraycopy(mod_Bytes_Extra, 1, mod_Bytes, 0, 128);
        byte[] exp_Bytes = exp_Int.toByteArray();
        String modulus = Base64.encodeToString(mod_Bytes, Base64.DEFAULT);
        String exponent = Base64.encodeToString(exp_Bytes, Base64.DEFAULT);
        System.out.println(modulus);
        System.out.println(exponent);
        String public_Xml = "<BitStrength>0124</BitStrength><RSAKeyValue><Modulus>"+modulus+"</Modulus><Exponent>"+exponent+"</Exponent></RSAKeyValue>";
    

    C#

    class KeyBuilder
        {
            private RSACryptoServiceProvider rsa;
    
            public RSACryptoServiceProvider CreateKey(string rsaKeyPair)
            {
                rsa = new RSACryptoServiceProvider();
                StringBuilder output = new StringBuilder();
                string xmlString = "<Key>" + rsaKeyPair + "</Key>";
                rsa.FromXmlString(xmlString);
                return rsa;
            }
        }
    

    Always make you read/write byte arrays with UTF-8 encoding on java side because Java by default uses Unicode encoding whereas C# uses UTF-8.

    Also byte arrays in java are signed whereas in C# they are unsigned. So if you have to parse binary data sent from Java code in C# side read it in a sbyte array.

    0 讨论(0)
  • 2021-01-16 03:05

    I found the answer in the PvkConvert.java file, which I've rewritten (in the relevant parts) as C# for use in Xamarin.Android apps as PvkConvert.cs.

    I learned that RSACryptoServiceProvider's native file format (when you use ExportCspBlob) is called PRIVATEKEYBLOB or PUBLICKEYBLOB (depending on whether the private key is included). Encoding a Java IPrivateKey as a PRIVATEKEYBLOB requires a few fields that evidently are only available on an originally generated IPrivateKey instance (one deserialized from storage does not cast to the necessary IRSAPrivateCrtKey interface.)

    0 讨论(0)
提交回复
热议问题