• RSA加密之C#格式与Java格式的转换


    .NET和Java中的密钥

    ASN.1、PKCS是最初的,也是最主要的RSA公钥和私钥的语法标准,被RSA Lab所维护。
    ASN.1、PKCS#1都定义了公钥和私钥的类型——序列化的数字。为了下一个层次的抽象(适当的包装),现在一般使用的组合是:PKCS#8的私钥,X.509的公钥 。
    PKCS语法主要用于私钥,其内部标准目前有10种。目前JAVA普遍使用的是PKCS#8,用作私钥格式。
    X.509语法主要用于公钥,广泛使用于web浏览器和SLL。 
    3种语法标准的公私钥可以实现相互转化,其核心为ASN1语法中的整数值(modulus,PublicExponent,privateExponent ),其余的数值都可以经过计算后得出。
     
    .NET使用的是标准的RSA格式,然后将其中的数字base64编码后,生成XML进行存储。
    java中使用的是PKCS#8,、X.509的公私钥语法,存储的都是相应的JAVA类自动生成的base64字符串。
    由于存储格式的区别,在相互转换、读取的时候,需要理解RSA相关的知识,才能正确使用类来转换。

    密钥格式

    c#公钥:

    <RSAKeyValue><Modulus>yuSIL2dWBUJbtEItaHKCBTJ28lQJyIql4+Ptu5kcjnCYOy5Z/FOzLoq4htyuH5Z1JamU+9IbZG5+hmR7St7hLvByJaK4Xkqw23amJOv5GvqoEieB0pf8Fp96WgIoYrNP/85Q8Rkltn9/16bLn0LI6WQNTb0S85wAHokNoi4/OhM=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>
    

    c#私钥:

    <RSAKeyValue><Modulus>yuSIL2dWBUJbtEItaHKCBTJ28lQJyIql4+Ptu5kcjnCYOy5Z/FOzLoq4htyuH5Z1JamU+9IbZG5+hmR7St7hLvByJaK4Xkqw23amJOv5GvqoEieB0pf8Fp96WgIoYrNP/85Q8Rkltn9/16bLn0LI6WQNTb0S85wAHokNoi4/OhM=</Modulus><Exponent>AQAB</Exponent><P>6YS3ZIEclzPX43CaX/ssaouHwUDpnL9dBfrHZs/YxjQS8KNtgl9H+kD3Thc+rl5wIyLPWeKFFiBJuRmziKkQjQ==</P><Q>3m0D/eebwUIcA93Kdu934hwmjxuxInD+iEKrLpMweQLSF5EkIHvkeFZkRc6xs0Hfjq960eJmTcfj+tE42I9dHw==</Q><DP>RAC3G1iSB+I8E2q+Ogc+JwTdEsUhgtkjcNNX8DPE7+tIPLWK9XVj05fJrP8N7N9pjoHbmlRh51Cdx36ZjsmVHQ==</DP><DQ>JRsAoHnj1PCnZcm5PfAjCrhxgkw3V6yL+cVNc16gpn9e9wmCglzIt36KCc86e9IQbmg90Ae50132XWBL4GzCNw==</DQ><InverseQ>nM8lxawgzM5kjXU7u8VpHFHpZ3ZdPZ7EVsHjnxBST4mt1LMW6hsQe8OQYzP0qH999+97P8q1RZ1oyQwRrrZK9g==</InverseQ><D>Kc2iXZn9+EFu4ZoM/wswzN9T8KPuDBq9CVJKBjAK2TJLu03Wjo20Sm+ci3Tmj22Rn3vsTWJB8JRvj0MewBNh88r3gmzTvE5HYrR/EP2FqGA7hlaqvXH2sAliMhCQLNkl3wVYjTazLvRv5jiCiGCt29UEIb0LhdgA3scbSrf+oZk=</D></RSAKeyValue>
    

    java公钥:

    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCOIakky8cbDGZCvoiHfmvb7nxpd8h/gxydvmAmAPyAzHH9Ij+aKRjukdxcPawnci4WpfUBaUlnhTbpDkyqjcYy/h/iabFGxW7MYV4cdsH2ilw7dUQyDSeDNozw7AjW4f1yNuMiFKDWOwXFz7I/qJkTQraVn1+AO3ZTezU5+2HrHwIDAQAB
    

    java私钥:

    MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAI4hqSTLxxsMZkK+iId+a9vufGl3yH+DHJ2+YCYA/IDMcf0iP5opGO6R3Fw9rCdyLhal9QFpSWeFNukOTKqNxjL+H+JpsUbFbsxhXhx2wfaKXDt1RDINJ4M2jPDsCNbh/XI24yIUoNY7BcXPsj+omRNCtpWfX4A7dlN7NTn7YesfAgMBAAECgYB0hoBH3JGWSWolWlRQ0YLYQwPY7A2DDRkO8p+dSL27UuI5aDTAzOTV4tvI+/8CMAg9JT5jM9CsgHjuRXzxb16IAhD/cZxWTHyyrtcSB6vaby88i9mGx7N1wxhDj4Rh7PfrI95siV/uszrL0CGJY6uN3zVUbs7IgkT8qPRFeR36cQJBAM+JYQDXCZFT8vv2wgDOkHle4EQbj/S3oefvMuYV97KXjgnku79SIxABvTyQMtulwNux22T8CaxM6sEVaISD480CQQCvUlYiicGp/CZ6uyhrdbMQ+OD5zb3KcKKt1MKlWiuS35F2xTQ4c3QPhGBX1hrqwMqF4KlSn/UQGk9+g+GtIPabAkArJxqXbR8dK8J7Z6yhNFJQGk0xfDWrob81lcQUmX6+kMrE/d2YA4Es49+wRx98EnQOemXvEoUEYZ3ydfwcibwFAkAZO2haIClXJYsELttqW84hqy/1w76E3CENk4lP8uJCiRqOVWNmnHcfpJWZDp9hGc4L5oF3+r1yS9cVBjX8jLnxAkEAiwFXB74VCWDns85ARG2XPgzKXl+cnUwTWoMxvPLDy7AbuNpPRM1NIc2R/ISH7qRNcAWi5DD+VoVsGYHkZQ0+XA==
    

    很明显他们的格式是不同的。

    现在需求是这样的使用java将公钥发出去,.net使用公钥加密,然后java再解密。
    先把java的加密方法放出来:

    package com.mantishell;
    
    import java.io.ByteArrayOutputStream;
    import java.security.KeyFactory;
    import java.security.KeyPair;
    import java.security.KeyPairGenerator;
    import java.security.PrivateKey;
    import java.security.PublicKey;
    import java.security.Signature;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    import javax.crypto.Cipher;
    import org.apache.commons.codec.binary.Base64;
    
    public class TestRsa {
    
        /**
         * RSA最大加密明文大小
         */
        private static final int MAX_ENCRYPT_BLOCK = 117;
    
        /**
         * RSA最大解密密文大小
         */
        private static final int MAX_DECRYPT_BLOCK = 128;
    
        /**
         * 获取密钥对
         *
         * @return 密钥对
         */
        public static KeyPair getKeyPair() throws Exception {
            KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
            generator.initialize(1024);
            return generator.generateKeyPair();
        }
    
        /**
         * 获取私钥
         *
         * @param privateKey 私钥字符串
         * @return
         */
        public static PrivateKey getPrivateKey(String privateKey) throws Exception {
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            byte[] decodedKey = Base64.decodeBase64(privateKey.getBytes());
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodedKey);
            return keyFactory.generatePrivate(keySpec);
        }
    
        /**
         * 获取公钥
         *
         * @param publicKey 公钥字符串
         * @return
         */
        public static PublicKey getPublicKey(String publicKey) throws Exception {
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            byte[] decodedKey = Base64.decodeBase64(publicKey.getBytes());
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodedKey);
            return keyFactory.generatePublic(keySpec);
        }
    
        /**
         * RSA加密
         *
         * @param data 待加密数据
         * @param publicKey 公钥
         * @return
         */
        public static String encrypt(String data, PublicKey publicKey) throws Exception {
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            int inputLen = data.getBytes().length;
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            int offset = 0;
            byte[] cache;
            int i = 0;
            // 对数据分段加密
            while (inputLen - offset > 0) {
                if (inputLen - offset > MAX_ENCRYPT_BLOCK) {
                    cache = cipher.doFinal(data.getBytes(), offset, MAX_ENCRYPT_BLOCK);
                } else {
                    cache = cipher.doFinal(data.getBytes(), offset, inputLen - offset);
                }
                out.write(cache, 0, cache.length);
                i++;
                offset = i * MAX_ENCRYPT_BLOCK;
            }
            byte[] encryptedData = out.toByteArray();
            out.close();
            // 获取加密内容使用base64进行编码,并以UTF-8为标准转化成字符串
            // 加密后的字符串
            return new String(Base64.encodeBase64String(encryptedData));
        }
    
        /**
         * RSA解密
         *
         * @param data 待解密数据
         * @param privateKey 私钥
         * @return
         */
        public static String decrypt(String data, PrivateKey privateKey) throws Exception {
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            byte[] dataBytes = Base64.decodeBase64(data);
            int inputLen = dataBytes.length;
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            int offset = 0;
            byte[] cache;
            int i = 0;
            // 对数据分段解密
            while (inputLen - offset > 0) {
                if (inputLen - offset > MAX_DECRYPT_BLOCK) {
                    cache = cipher.doFinal(dataBytes, offset, MAX_DECRYPT_BLOCK);
                } else {
                    cache = cipher.doFinal(dataBytes, offset, inputLen - offset);
                }
                out.write(cache, 0, cache.length);
                i++;
                offset = i * MAX_DECRYPT_BLOCK;
            }
            byte[] decryptedData = out.toByteArray();
            out.close();
            // 解密后的内容
            return new String(decryptedData, "UTF-8");
        }
    
        /**
         * 签名
         *
         * @param data 待签名数据
         * @param privateKey 私钥
         * @return 签名
         */
        public static String sign(String data, PrivateKey privateKey) throws Exception {
            byte[] keyBytes = privateKey.getEncoded();
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PrivateKey key = keyFactory.generatePrivate(keySpec);
            Signature signature = Signature.getInstance("MD5withRSA");
            signature.initSign(key);
            signature.update(data.getBytes());
            return new String(Base64.encodeBase64(signature.sign()));
        }
    
        /**
         * 验签
         *
         * @param srcData 原始字符串
         * @param publicKey 公钥
         * @param sign 签名
         * @return 是否验签通过
         */
        public static boolean verify(String srcData, PublicKey publicKey, String sign) throws Exception {
            byte[] keyBytes = publicKey.getEncoded();
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PublicKey key = keyFactory.generatePublic(keySpec);
            Signature signature = Signature.getInstance("MD5withRSA");
            signature.initVerify(key);
            signature.update(srcData.getBytes());
            return signature.verify(Base64.decodeBase64(sign.getBytes()));
        }
    
        public static void main(String[] args) throws Exception{
            TestSimple();
        }
        public static void TestSimple(){
            try {
                // 生成密钥对
                KeyPair keyPair = getKeyPair();
                String privateKey = new String(Base64.encodeBase64(keyPair.getPrivate().getEncoded()));
                String publicKey = new String(Base64.encodeBase64(keyPair.getPublic().getEncoded()));
                System.out.println("私钥:" + privateKey);
                System.out.println("公钥:" + publicKey);
                // RSA加密
                String data = "待加密的文字内容";
                String encryptData = encrypt(data, getPublicKey(publicKey));
                System.out.println("加密后内容:" + encryptData);
                // RSA解密
                String decryptData = decrypt(encryptData, getPrivateKey(privateKey));
                System.out.println("解密后内容:" + decryptData);
    
                // RSA签名
                String sign = sign(data, getPrivateKey(privateKey));
                // RSA验签
                boolean result = verify(data, getPublicKey(publicKey), sign);
                System.out.print("验签结果:" + result);
            } catch (Exception e) {
                e.printStackTrace();
                System.out.print("加解密异常");
            }
        }
    }
    

    这里需要添加一下maven的坐标:

            <dependency>
                <groupId>commons-codec</groupId>
                <artifactId>commons-codec</artifactId>
                <version>1.14</version>
            </dependency>
    

    现在生成的公钥就是这么一串字符串:

    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCOIakky8cbDGZCvoiHfmvb7nxpd8h/gxydvmAmAPyAzHH9Ij+aKRjukdxcPawnci4WpfUBaUlnhTbpDkyqjcYy/h/iabFGxW7MYV4cdsH2ilw7dUQyDSeDNozw7AjW4f1yNuMiFKDWOwXFz7I/qJkTQraVn1+AO3ZTezU5+2HrHwIDAQAB
    

    Java公钥转为C#公钥(C#代码)

    C#中的公私钥使用XML字符串进行存储,读取时直接读入字符串即可。
    由于C#使用的是标准的RSA格式,因此JAVA的RSAPublicKeySpec、RSAPrivateKeySpec配置类的核心参数(modulus,PublicExponent,privateExponent )都可以从对应XML中的节点值(Modulus-modulus 、Exponent-PublicExponent 、D-privateExponent )base64解码后获取。然后将其传入JAVA配置类中,然后根据配置类生成相应的RSA公私钥。

    客户端.net平台下如何操作呢?
    需要安装BouncyCastle包。
    首先需要将公钥转换成.net平台认识的格式:

    var keyStr = CryptoHelper.RsaPublicKeyJava2DotNet(publicKeyStr);//publicKeyStr就是公钥,返回.net平台认识的RSA公钥格式
    
    using Org.BouncyCastle.Security;
    using Org.BouncyCastle.Crypto.Parameters;
    //上面两句引用必不可少
    
            /// <summary>    
            /// RSA公钥格式转换,java->.net    
            /// </summary>    
            /// <param name="publicKey">java生成的公钥</param>    
            /// <returns></returns>    
            public static string RsaPublicKeyJava2DotNet(string publicKey)
            {
                RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey));
                return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent></RSAKeyValue>",
                    Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned()),
                    Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned()));
            }
    //还不能少了package
    <package id="BouncyCastle" version="1.8.5" targetFramework="net45" />
    

    转换完成后,将传送的字符串进行加密处理:

            /// <summary>
            /// RSA加密 将公钥导入到RSA对象中,准备加密
            /// </summary>
            /// <param name="publicKey">公钥</param>
            /// <param name="encryptstring">待加密的字符串</param>
            public static string RsaEncrypt(string publicKey, string encryptstring)
            {
                using (var rsaProvider = new RSACryptoServiceProvider())
                {
                    var inputBytes = Encoding.UTF8.GetBytes(encryptstring);//有含义的字符串转化为字节流
                    rsaProvider.FromXmlString(publicKey);//载入公钥
                    int bufferSize = (rsaProvider.KeySize / 8) - 11;//单块最大长度
                    var buffer = new byte[bufferSize];
                    using (MemoryStream inputStream = new MemoryStream(inputBytes),outputStream = new MemoryStream())
                    {
                        while (true)
                        { //分段加密
                            int readSize = inputStream.Read(buffer, 0, bufferSize);
                            if (readSize <= 0)
                            {
                                break;
                            }
                            var temp = new byte[readSize];
                            Array.Copy(buffer, 0, temp, 0, readSize);
                            var encryptedBytes = rsaProvider.Encrypt(temp, false);
                            outputStream.Write(encryptedBytes, 0, encryptedBytes.Length);
                        }
                        return Convert.ToBase64String(outputStream.ToArray());//转化为字节流方便传输
                    }
                }
            }
    

    分段加密是因为数据多的话,报“不正确的长度”的异常。

    然后使用C#语言加密,加密完成后,把加密后的字符串给java平台去解密即可,java拿加密后的字符串和存储的私钥进行解密即可得到明文。

    下面是两个类:
    RsaHelper.cs

    using System;
    using System.IO;
    using System.Security.Cryptography;
    using System.Text;
    
    
            /// <summary>
            /// 生成密钥
            /// <param name="privateKey">私钥</param>
            /// <param name="publicKey">公钥</param>
            /// <param name="keySize">密钥长度:512,1024,2048,4096,8192</param>
            /// </summary>
            public static void Generator(out string privateKey, out string publicKey, int keySize = 1024)
            {
                RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(keySize);
                privateKey = rsa.ToXmlString(true); //将RSA算法的私钥导出到字符串PrivateKey中 参数为true表示导出私钥 true 表示同时包含 RSA 公钥和私钥;false 表示仅包含公钥。
                publicKey = rsa.ToXmlString(false); //将RSA算法的公钥导出到字符串PublicKey中 参数为false表示不导出私钥 true 表示同时包含 RSA 公钥和私钥;false 表示仅包含公钥。
            }
            /// <summary>
            /// RSA加密 将公钥导入到RSA对象中,准备加密
            /// </summary>
            /// <param name="publicKey">公钥</param>
            /// <param name="encryptstring">待加密的字符串</param>
            public static string RsaEncrypt(string publicKey, string encryptstring)
            {
                using (var rsaProvider = new RSACryptoServiceProvider())
                {
                    var inputBytes = Encoding.UTF8.GetBytes(encryptstring);//有含义的字符串转化为字节流
                    rsaProvider.FromXmlString(publicKey);//载入公钥
                    int bufferSize = (rsaProvider.KeySize / 8) - 11;//单块最大长度
                    var buffer = new byte[bufferSize];
                    using (MemoryStream inputStream = new MemoryStream(inputBytes),outputStream = new MemoryStream())
                    {
                        while (true)
                        { //分段加密
                            int readSize = inputStream.Read(buffer, 0, bufferSize);
                            if (readSize <= 0)
                            {
                                break;
                            }
                            var temp = new byte[readSize];
                            Array.Copy(buffer, 0, temp, 0, readSize);
                            var encryptedBytes = rsaProvider.Encrypt(temp, false);
                            outputStream.Write(encryptedBytes, 0, encryptedBytes.Length);
                        }
                        return Convert.ToBase64String(outputStream.ToArray());//转化为字节流方便传输
                    }
                }
            }
    

    CryptoHelper.cs

    using System;
    using System.IO;
    using System.Security.Cryptography;
    using System.Xml;
    using Org.BouncyCastle.Asn1.Pkcs;
    using Org.BouncyCastle.Asn1.X509;
    using Org.BouncyCastle.Crypto;
    using Org.BouncyCastle.Crypto.Parameters;
    using Org.BouncyCastle.Math;
    using Org.BouncyCastle.Pkcs;
    using Org.BouncyCastle.Security;
    using Org.BouncyCastle.X509;
    
    
            /// <summary>
            /// RSA密钥转Pem密钥
            /// </summary>
            /// <param name="RSAKey">RSA密钥</param>
            /// <param name="isPrivateKey">是否是私钥</param>
            /// <returns>Pem密钥</returns>
            public static string RsaKeyToPem(string RSAKey, bool isPrivateKey)
            {
                string pemKey = string.Empty;
                var rsa = new RSACryptoServiceProvider();
                rsa.FromXmlString(RSAKey);
                RSAParameters rsaPara = new RSAParameters();
                RsaKeyParameters key = null;
                //RSA私钥
                if (isPrivateKey)
                {
                    rsaPara = rsa.ExportParameters(true);
                    key = new RsaPrivateCrtKeyParameters(
                        new BigInteger(1, rsaPara.Modulus), new BigInteger(1, rsaPara.Exponent),
                        new BigInteger(1, rsaPara.D),
                        new BigInteger(1, rsaPara.P), new BigInteger(1, rsaPara.Q), new BigInteger(1, rsaPara.DP),
                        new BigInteger(1, rsaPara.DQ),
                        new BigInteger(1, rsaPara.InverseQ));
                }
                //RSA公钥
                else
                {
                    rsaPara = rsa.ExportParameters(false);
                    key = new RsaKeyParameters(false,
                        new BigInteger(1, rsaPara.Modulus),
                        new BigInteger(1, rsaPara.Exponent));
                }
                using (TextWriter sw = new StringWriter())
                {
                    var pemWriter = new Org.BouncyCastle.OpenSsl.PemWriter(sw);
                    pemWriter.WriteObject(key);
                    pemWriter.Writer.Flush();
                    pemKey = sw.ToString();
                }
                return pemKey;
            }
    
            /// <summary>
            /// Pem密钥转RSA密钥
            /// </summary>
            /// <param name="pemKey">Pem密钥</param>
            /// <param name="isPrivateKey">是否是私钥</param>
            /// <returns>RSA密钥</returns>
            public static string PemToRsaKey(string pemKey, bool isPrivateKey = false)
            {
                string rsaKey = string.Empty;
                object pemObject = null;
                RSAParameters rsaPara = new RSAParameters();
                using (StringReader sReader = new StringReader(pemKey))
                {
                    var pemReader = new Org.BouncyCastle.OpenSsl.PemReader(sReader);
                    pemObject = pemReader.ReadObject();
                }
                //RSA私钥
                if (isPrivateKey)
                {
                    RsaPrivateCrtKeyParameters key =
                        (RsaPrivateCrtKeyParameters)((AsymmetricCipherKeyPair)pemObject).Private;
                    rsaPara = new RSAParameters
                    {
                        Modulus = key.Modulus.ToByteArrayUnsigned(),
                        Exponent = key.PublicExponent.ToByteArrayUnsigned(),
                        D = key.Exponent.ToByteArrayUnsigned(),
                        P = key.P.ToByteArrayUnsigned(),
                        Q = key.Q.ToByteArrayUnsigned(),
                        DP = key.DP.ToByteArrayUnsigned(),
                        DQ = key.DQ.ToByteArrayUnsigned(),
                        InverseQ = key.QInv.ToByteArrayUnsigned(),
                    };
                }
                //RSA公钥
                else
                {
                    RsaKeyParameters key = (RsaKeyParameters)pemObject;
                    rsaPara = new RSAParameters
                    {
                        Modulus = key.Modulus.ToByteArrayUnsigned(),
                        Exponent = key.Exponent.ToByteArrayUnsigned(),
                    };
                }
                RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
                rsa.ImportParameters(rsaPara);
                using (StringWriter sw = new StringWriter())
                {
                    sw.Write(rsa.ToXmlString(isPrivateKey ? true : false));
                    rsaKey = sw.ToString();
                }
                return rsaKey;
            }
    
            /// <summary>    
            /// RSA私钥格式转换,java->.net    
            /// </summary>    
            /// <param name="privateKey">java生成的RSA私钥</param>    
            /// <returns></returns>   
            public static string RsaPrivateKeyJava2DotNet(string privateKey)
            {
                RsaPrivateCrtKeyParameters privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKey));
                return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent><P>{2}</P><Q>{3}</Q><DP>{4}</DP><DQ>{5}</DQ><InverseQ>{6}</InverseQ><D>{7}</D></RSAKeyValue>",
                Convert.ToBase64String(privateKeyParam.Modulus.ToByteArrayUnsigned()),
                Convert.ToBase64String(privateKeyParam.PublicExponent.ToByteArrayUnsigned()),
                Convert.ToBase64String(privateKeyParam.P.ToByteArrayUnsigned()),
                Convert.ToBase64String(privateKeyParam.Q.ToByteArrayUnsigned()),
                Convert.ToBase64String(privateKeyParam.DP.ToByteArrayUnsigned()),
                Convert.ToBase64String(privateKeyParam.DQ.ToByteArrayUnsigned()),
                Convert.ToBase64String(privateKeyParam.QInv.ToByteArrayUnsigned()),
                Convert.ToBase64String(privateKeyParam.Exponent.ToByteArrayUnsigned()));
            }
            /// <summary>    
            /// RSA私钥格式转换,.net->java    
            /// </summary>    
            /// <param name="privateKey">.net生成的私钥</param>    
            /// <returns></returns>   
            public static string RsaPrivateKeyDotNet2Java(string privateKey)
            {
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(privateKey);
                if (doc.DocumentElement == null)
                {
                    return null;
                }
                BigInteger m = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Modulus")[0].InnerText));
                BigInteger exp = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Exponent")[0].InnerText));
                BigInteger d = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("D")[0].InnerText));
                BigInteger p = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("P")[0].InnerText));
                BigInteger q = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Q")[0].InnerText));
                BigInteger dp = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("DP")[0].InnerText));
                BigInteger dq = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("DQ")[0].InnerText));
                BigInteger qinv = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("InverseQ")[0].InnerText));
                RsaPrivateCrtKeyParameters privateKeyParam = new RsaPrivateCrtKeyParameters(m, exp, d, p, q, dp, dq, qinv);
                PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKeyParam);
                byte[] serializedPrivateBytes = privateKeyInfo.ToAsn1Object().GetEncoded();
                return Convert.ToBase64String(serializedPrivateBytes);
            }
            /// <summary>    
            /// RSA公钥格式转换,java->.net    
            /// </summary>    
            /// <param name="publicKey">java生成的公钥</param>    
            /// <returns></returns>    
            public static string RsaPublicKeyJava2DotNet(string publicKey)
            {
                RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey));
                return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent></RSAKeyValue>",
                    Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned()),
                    Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned()));
            }
            /// <summary>    
            /// RSA公钥格式转换,.net->java    
            /// </summary>    
            /// <param name="publicKey">.net生成的公钥</param>    
            /// <returns></returns>   
            public static string RsaPublicKeyDotNet2Java(string publicKey)
            {
                XmlDocument doc = new XmlDocument(); 
                doc.LoadXml(publicKey);
                if (doc.DocumentElement == null)
                {
                    return null;
                }
                BigInteger m = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Modulus")[0].InnerText));
                BigInteger p = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Exponent")[0].InnerText));
                RsaKeyParameters pub = new RsaKeyParameters(false, m, p);
                SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pub);
                byte[] serializedPublicBytes = publicKeyInfo.ToAsn1Object().GetDerEncoded();
                return Convert.ToBase64String(serializedPublicBytes);
            }
    
  • 相关阅读:
    关于unity的一个不错的插件平台
    erlang otp中的socket参数设置
    android开发国内镜像
    composer中文镜像
    bootstrap的一些资源
    根据现有表操作基于active record的model
    Erlang Web 监控工具
    erlang程序发布的时候需要注意的地方
    pcl学习笔记(二):点云类型
    c++中inline函数的意义
  • 原文地址:https://www.cnblogs.com/mantishell/p/12574241.html
Copyright © 2020-2023  润新知