• java与.net平台之间进行RSA加密验证


    RSA加密算法虽然不分平台,标准都是一样的,但是各个平台的实现方式都不尽相同,下面来我来说说
    java与.net平台之间该如何进行RSA加密验证,
    java端加密-》.net端验证.net端加密-》java端验证

    我对RSA算法也只是停留在应用的层面,所以我就以应用的角度来说说这个过程。
    首先,我们来看一下java端的私钥和公钥的样子:
    私钥:

    MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBAL6VJN4ZkfZA3aPPgKC3xaqT/yZT5FOlQ5TGg6heVqDVEHHVLH1E+HEEmWmuTv2ngz9pZbzy9KWkJpV59W1dgNHSSk575VjUAv0BhZXFSH0lng2mZ2Q5/2dVxKsASjJ2bQiEGUD8LO5KpaLlfQpo3ANovBZvUtHw5exegnyXyZbDAgMBAAECgYEAr7YEWr1KhLcDYg9jMUqd9QokOSspnTEGoPlx016/EeO/GKSJMynOwSyTYQszisvRxzoecdmyU7GHXVMnQ2Ds7WvbcuNkIRWmxFa4nTkk2zNF6KByvvFwLiW4LQXF6B+uV7+ZNqvfhCoD/j2wki8jfWkuuAaKnTda/axHMi+zRYECQQD73iC2GjZyur4amJQPK6d+kDlJ0dYyyUvQa0vd6mfoPnQDOIqayBaueSwWIpLI/L7eUuP9CDFryQtdBvWqD/dBAkEAwbWcrybn0eaxiPZacZLZXzXO8g12hYoXT1h0DTLvy1rnVUOspNfKZcBZMjPxT4+QEknoTShSnSbJ5sHitfZxAwJBANMlU2z2KqEh1k77jFvvb9oVVEGDbTtkL2+JE6/1W6iB+sXcd63sgb9Ai+n+j+l4oRZGjSTJ4oyGnUUemYI5IkECQQCA9JNrcv4PGYIFCOPrCfTV0m+Dan0Fp4mfE+amRsumWEz60UOktdeS53s51aSG767czgDtJLPi1MjCaz6vHnHbAkEA4NxLLg6UCAoCpXMgqqZHWMgbMwNNFr9diCWP/tZ5OJmWYHgn7zfqMXa/RNaethjdG1biIkj5h7qm6XDBBqGuxw==


    公钥:

    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+lSTeGZH2QN2jz4Cgt8Wqk/8mU+RTpUOUxoOoXlag1RBx1Sx9RPhxBJlprk79p4M/aWW88vSlpCaVefVtXYDR0kpOe+VY1AL9AYWVxUh9JZ4NpmdkOf9nVcSrAEoydm0IhBlA/CzuSqWi5X0KaNwDaLwWb1LR8OXsXoJ8l8mWwwIDAQAB


    我们再来看一下.net端的私钥和公钥的样子:
    私钥:

    <RSAKeyValue><Modulus>vpUk3hmR9kDdo8+AoLfFqpP/JlPkU6VDlMaDqF5WoNUQcdUsfUT4cQSZaa5O/aeDP2llvPL0paQmlXn1bV2A0dJKTnvlWNQC/QGFlcVIfSWeDaZnZDn/Z1XEqwBKMnZtCIQZQPws7kqlouV9CmjcA2i8Fm9S0fDl7F6CfJfJlsM=</Modulus><Exponent>AQAB</Exponent><P>+94gtho2crq+GpiUDyunfpA5SdHWMslL0GtL3epn6D50AziKmsgWrnksFiKSyPy+3lLj/Qgxa8kLXQb1qg/3QQ==</P><Q>wbWcrybn0eaxiPZacZLZXzXO8g12hYoXT1h0DTLvy1rnVUOspNfKZcBZMjPxT4+QEknoTShSnSbJ5sHitfZxAw==</Q><DP>0yVTbPYqoSHWTvuMW+9v2hVUQYNtO2Qvb4kTr/VbqIH6xdx3reyBv0CL6f6P6XihFkaNJMnijIadRR6ZgjkiQQ==</DP><DQ>gPSTa3L+DxmCBQjj6wn01dJvg2p9BaeJnxPmpkbLplhM+tFDpLXXkud7OdWkhu+u3M4A7SSz4tTIwms+rx5x2w==</DQ><InverseQ>4NxLLg6UCAoCpXMgqqZHWMgbMwNNFr9diCWP/tZ5OJmWYHgn7zfqMXa/RNaethjdG1biIkj5h7qm6XDBBqGuxw==</InverseQ><D>r7YEWr1KhLcDYg9jMUqd9QokOSspnTEGoPlx016/EeO/GKSJMynOwSyTYQszisvRxzoecdmyU7GHXVMnQ2Ds7WvbcuNkIRWmxFa4nTkk2zNF6KByvvFwLiW4LQXF6B+uV7+ZNqvfhCoD/j2wki8jfWkuuAaKnTda/axHMi+zRYE=</D></RSAKeyValue>


    公钥:

    <RSAKeyValue><Modulus>vpUk3hmR9kDdo8+AoLfFqpP/JlPkU6VDlMaDqF5WoNUQcdUsfUT4cQSZaa5O/aeDP2llvPL0paQmlXn1bV2A0dJKTnvlWNQC/QGFlcVIfSWeDaZnZDn/Z1XEqwBKMnZtCIQZQPws7kqlouV9CmjcA2i8Fm9S0fDl7F6CfJfJlsM=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>


    所以,只要将一边的公钥和私钥转换成另一边的即可。
    我的做法是将java端的公钥和私钥转换成.net端的公钥和私钥。

    咱们先看私钥的转换:

    // --- Returns XML encoded RSA private key string suitable for .NET
        // CryptoServiceProvider.FromXmlString(true) ------
        // --- Leading zero bytes (most significant) must be removed for XML
        // encoding for .NET; otherwise format error ---

        private String getRSAPrivateKeyAsNetFormat(byte[] encodedPrivkey) {
            try {
                StringBuffer buff = new StringBuffer(1024);

                PKCS8EncodedKeySpec pvkKeySpec = new PKCS8EncodedKeySpec(
                        encodedPrivkey);
                KeyFactory keyFactory = KeyFactory.getInstance("RSA");
                RSAPrivateCrtKey pvkKey = (RSAPrivateCrtKey) keyFactory
                        .generatePrivate(pvkKeySpec);

                buff.append("<RSAKeyValue>");
                buff.append("<Modulus>"
                        + b64encode(removeMSZero(pvkKey.getModulus().toByteArray()))
                        + "</Modulus>");

                buff.append("<Exponent>"
                        + b64encode(removeMSZero(pvkKey.getPublicExponent()
                                .toByteArray())) + "</Exponent>");

                buff.append("<P>"
                        + b64encode(removeMSZero(pvkKey.getPrimeP().toByteArray()))
                        + "</P>");

                buff.append("<Q>"
                        + b64encode(removeMSZero(pvkKey.getPrimeQ().toByteArray()))
                        + "</Q>");

                buff.append("<DP>"
                        + b64encode(removeMSZero(pvkKey.getPrimeExponentP()
                                .toByteArray())) + "</DP>");

                buff.append("<DQ>"
                        + b64encode(removeMSZero(pvkKey.getPrimeExponentQ()
                                .toByteArray())) + "</DQ>");

                buff.append("<InverseQ>"
                        + b64encode(removeMSZero(pvkKey.getCrtCoefficient()
                                .toByteArray())) + "</InverseQ>");

                buff.append("<D>"
                        + b64encode(removeMSZero(pvkKey.getPrivateExponent()
                                .toByteArray())) + "</D>");
                buff.append("</RSAKeyValue>");

                return buff.toString().replaceAll("[  ]", "");
            } catch (Exception e) {
                System.err.println(e);
                return null;
            }
        }


    再看公钥的转换:

    // --- Returns XML encoded RSA public key string suitable for .NET
        // CryptoServiceProvider.FromXmlString(true) ------
        // --- Leading zero bytes (most significant) must be removed for XML
        // encoding for .NET; otherwise format error ---

        private String getRSAPublicKeyAsNetFormat(byte[] encodedPrivkey) {
            try {
                StringBuffer buff = new StringBuffer(1024);

                PKCS8EncodedKeySpec pvkKeySpec = new PKCS8EncodedKeySpec(
                        encodedPrivkey);
                KeyFactory keyFactory = KeyFactory.getInstance("RSA");
                RSAPrivateCrtKey pvkKey = (RSAPrivateCrtKey) keyFactory
                        .generatePrivate(pvkKeySpec);
                buff.append("<RSAKeyValue>");
                buff.append("<Modulus>"
                        + b64encode(removeMSZero(pvkKey.getModulus().toByteArray()))
                        + "</Modulus>");
                buff.append("<Exponent>"
                        + b64encode(removeMSZero(pvkKey.getPublicExponent()
                                .toByteArray())) + "</Exponent>");
                buff.append("</RSAKeyValue>");
                return buff.toString().replaceAll("[  ]", "");
            } catch (Exception e) {
                System.err.println(e);
                return null;
            }
        }


    通过以上两个方法,就可以将java端的公钥和私钥转换为.net端的了。
    然后.net端可以用如下代码装载转换好的key

     //java端转换为.net端的私钥 
                    string NET_PRIVATE_KEY = @"<RSAKeyValue><Modulus>lKc3QnhdBGrA+Tkz0QvbgEWHDjS/AMp4bhwqFgQXdo+mIwC/8POr8GpgCpsY2GgU+PBIFI51q2U64aKFwQYQhxSiQI3r7kAa5+DVQVhheRlAaHz/iRMr2HqVkxqtjoTbNjVCMuTqgX7xu30YDcX9ZXSH0lGWCy3NEdzxBpOAtFk=</Modulus><Exponent>AQAB</Exponent><P>3eX5uQZalJF/tgosNUUV8ss4aVAwDntID63Ta6bFEnZFzp3YckXKGzmOQuygHK0tuUviN+BQFlk0eelMz3JMiQ==</P><Q>q3+YtH0B30ijTITtGWqNI+zXbhpodhVuugWHkihz9XKFQ7srbYA3YovvyOmK1Q/zlF92X3MFfUjRFWB/fEVVUQ==</Q><DP>Ey1tB7Ck43Ivt2vppjDyVKl7lp53iMje0XwUaZlgLthJ8DF0I2wkq3Wt9dq9e7z71qfYRTv9r/DFuEORf9xBAQ==</DP><DQ>n2ynDSmkIugIfeqX6meluv7BqWW9NABqhVz8kT8vxLzn63XEQi/NzLtfdbq8x6HjgktX5BUtxjB5xVCGUoS1cQ==</DQ><InverseQ>FNZDF90zR/2b/kevm4DomVTs7Iz/oaidOFsLQqD4BZfycuMdpTMAO8UUVtK5+eL7G24JaJAmb1U6QfkTc4syOQ==</InverseQ><D>cVf2aHZB5kZHkT+uZKx31xwsWAabxEyc+sf6xwKjqUDqWjIOJ/iDlzJkvHF5xjfGFfGP5CyjR+ZNuREkjwLCwjBiOhp34QMuN22LbKfHsvgHYiAOqkTxwASQ2FwaonA8nrfluHZhWECMrOSYag2QWuaOoToF91XvkNf8tBFcHQE=</D></RSAKeyValue>";
                    //java端转换为.net端的公钥     
                    //string NET_PUBLIC_KEY = @"<RSAKeyValue><Modulus>vpUk3hmR9kDdo8+AoLfFqpP/JlPkU6VDlMaDqF5WoNUQcdUsfUT4cQSZaa5O/aeDP2llvPL0paQmlXn1bV2A0dJKTnvlWNQC/QGFlcVIfSWeDaZnZDn/Z1XEqwBKMnZtCIQZQPws7kqlouV9CmjcA2i8Fm9S0fDl7F6CfJfJlsM=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
                    RSA = new RSACryptoServiceProvider();
                    RSA.FromXmlString(NET_PRIVATE_KEY);
                   //RSA.FromXmlString(NET_PUBLIC_KEY);



    注意,如果.net端只是验证,可以只导入NET_PUBLIC_KEY;如果.net端既加密又验证,那么只导入NET_PRIVATE_KEY即可,不用导入NET_PUBLIC_KEY。

    下面给出完整代码及使用说明:
    使用说明:
    1.使用java端的GenerateKeys方法,生成java端和.net端需要的公钥和私钥
    2.java端调用Sign方法进行加密,调用Verify方法进行验证
    3..net端调用signData方法进行加密,调用verifySignature方法进行验证

    .net端c#代码:

    using System;
    using System.Security.Cryptography;
    using System.IO;
    using System.Text;
    using System.Xml;
    using System.Web;
    namespace RSASecurity
    {
        class ssosign
        {
            private RSAParameters RSAKeyInfo;
            private static RSACryptoServiceProvider RSA=null;
            //私钥
            private const string NET_PRIVATE_KEY = @"<RSAKeyValue><Modulus>lKc3QnhdBGrA+Tkz0QvbgEWHDjS/AMp4bhwqFgQXdo+mIwC/8POr8GpgCpsY2GgU+PBIFI51q2U64aKFwQYQhxSiQI3r7kAa5+DVQVhheRlAaHz/iRMr2HqVkxqtjoTbNjVCMuTqgX7xu30YDcX9ZXSH0lGWCy3NEdzxBpOAtFk=</Modulus><Exponent>AQAB</Exponent><P>3eX5uQZalJF/tgosNUUV8ss4aVAwDntID63Ta6bFEnZFzp3YckXKGzmOQuygHK0tuUviN+BQFlk0eelMz3JMiQ==</P><Q>q3+YtH0B30ijTITtGWqNI+zXbhpodhVuugWHkihz9XKFQ7srbYA3YovvyOmK1Q/zlF92X3MFfUjRFWB/fEVVUQ==</Q><DP>Ey1tB7Ck43Ivt2vppjDyVKl7lp53iMje0XwUaZlgLthJ8DF0I2wkq3Wt9dq9e7z71qfYRTv9r/DFuEORf9xBAQ==</DP><DQ>n2ynDSmkIugIfeqX6meluv7BqWW9NABqhVz8kT8vxLzn63XEQi/NzLtfdbq8x6HjgktX5BUtxjB5xVCGUoS1cQ==</DQ><InverseQ>FNZDF90zR/2b/kevm4DomVTs7Iz/oaidOFsLQqD4BZfycuMdpTMAO8UUVtK5+eL7G24JaJAmb1U6QfkTc4syOQ==</InverseQ><D>cVf2aHZB5kZHkT+uZKx31xwsWAabxEyc+sf6xwKjqUDqWjIOJ/iDlzJkvHF5xjfGFfGP5CyjR+ZNuREkjwLCwjBiOhp34QMuN22LbKfHsvgHYiAOqkTxwASQ2FwaonA8nrfluHZhWECMrOSYag2QWuaOoToF91XvkNf8tBFcHQE=</D></RSAKeyValue>";
            //公钥参数
            private const string PUB_KEY_MODULES = @"1lpnLvumD8/NedJ7s4WS8UO9OORbXVTgJXmfa72bI4A1L1l6Np91BETQ+yB8Fq6iGWw5OR8OB2UbRBcopb2etepDqWd7kmCtbVT36kTW+E8dWdaVjbI2BCXEGaXuzPPdGOlp52OaawYR5zyG0MiCvJ4jE7RDJax4Cl24ZqPUs4U=";
            //公钥参数
            private const string PUB_KEY_EXP = @"AQAB";
            /// <summary>
            /// Reads the Public key file and Loads the RSAParameters with the 
            /// Modulous and Exponent data.
            /// </summary>
            public ssosign(RSAType type)
            {
                
                RSA = new RSACryptoServiceProvider();
                //if (type == RSAType.ITDMS)
                //{
                //    RSAKeyInfo = new RSAParameters();
                //    RSAKeyInfo.Modulus = Convert.FromBase64String(PUB_KEY_MODULES);
                //    RSAKeyInfo.Exponent = Convert.FromBase64String(PUB_KEY_EXP);
                //    RSA.ImportParameters(RSAKeyInfo);
                //}
                //else //type == RSAType.RSP
                //{ 
                    RSA.FromXmlString(NET_PRIVATE_KEY);
                //}
            }
            /// <summary>
            /// sign the data
            /// </summary>
            /// <param name="dataToBeSigned"></param>
            /// <returns></returns>
            public string signData(string dataToBeSigned)
            {
                byte[] data = Encoding.UTF8.GetBytes(dataToBeSigned);

                byte[] endata = RSA.SignData(data,"SHA1");

                return Convert.ToBase64String(endata);
               
            }
            /// <summary>
            /// Verifies the signature for a given data.
            /// </summary>
            /// <param name="signature">Signature data in Base64</param>
            /// <param name="signedData">Original data in BASE64</param>
            /// <returns>True if signature is valid else False</returns>
            public bool verifySignature(string signature,string signedData)
            {
                byte[] sign = Convert.FromBase64String(signature);
                return verifySignature(sign,signedData);
            }
            /// <summary>
            /// Verifies the signature for a given data.
            /// </summary>
            /// <param name="signature">The signature </param>
            /// <param name="signedData">Original data in Base64</param>
            /// <returns></returns>
            public bool verifySignature(byte[] signature , string signedData)
            {
                try
                {
                    byte[] hash = Convert.FromBase64String(signedData);
                    if(RSA.VerifyData(hash,"SHA1",signature))
                    {
                        return true;
                    }
                    else
                    {
                        //Console.WriteLine("The signature is not valid.");
                        return false;
                    }
                }
                catch(Exception e)    
                {
                    Console.WriteLine(e.Message);
                    return false;
                }
            }

            /// <summary>
            /// The main entry point for the application.
            /// </summary>
            [STAThread]
            static void Main()
            {
                ssosign sso = new ssosign(RSAType.RSP);
                string user = "limt";
                string time = "2010-12-01 11:00:00";
                string data = user + time;
                string endata = Convert.ToBase64String(Encoding.UTF8.GetBytes(data));
                //string ensignature = @"SjAoGfsw+vjTLOEC7eXq+V41Q6UNdRXVIdD+5gTbEfy8tfE8cgDIZRn4uIAydYfqprhJ2GbJnTTpQZxOJ0PsQR9TUVVGp0QmbNOJc/Zjm0kuBBwF43ESTSMe0CpXqOLMpLasP7hEdJlVgcrEIXijde0GxSD7qZ+6Ty8P0istR1Y=";
                string ensignature = sso.signData(data);

                bool result = sso.verifySignature(ensignature, endata);

                Console.WriteLine("Data is validate: " + result);
                //string str = HttpUtility.UrlDecode("MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OQ%3D%3D",Encoding.UTF8);
                //Console.WriteLine(str);
                Console.ReadLine();
            }
        }
    }


    java端代码:

    package rsa;

    import java.security.*;
    import java.security.spec.*;
    import java.io.*;
    import java.security.interfaces.*;

    import org.castor.util.Base64Decoder;
    import org.castor.util.Base64Encoder;


    public class ssosign {

        private KeyPairGenerator keyGen; // Key pair generator for RSA
        private PrivateKey privateKey; // Private Key Class
        private PublicKey publicKey; // Public Key Class
        private KeyPair keypair; // KeyPair Class
        private Signature sign; // Signature, used to sign the data

        /**
         * Default Constructor. Instantiates the signature algorithm.
         */
        public ssosign() {
            try {
                // Get the instance of Signature Engine.
                sign = Signature.getInstance("SHA1withRSA");
            } catch (NoSuchAlgorithmException nsa) {
                System.out.println("" + nsa.getMessage());
            }
        }

        /**
         * Signs the data and return the signature for a given data.
         * 
         * @param user
         *            The current user’s external person number
         * @param time
         *            The current time in string format: yyyy-mm-dd hh:mm:ss
         * @param EncodedCert
         *            The hard coded certificate string, i.e. <b>private key</b>
         * @return String URLEncode string of Signature
         * @throws UnsupportedEncodingException
         */
        public String Sign(String user, String time, String EncodedCert) {

            String returnStr = "";
            try {
                String toBeSigned = user + time;
                byte[] signature = signData(toBeSigned.getBytes(), EncodedCert);
                String base64Signature = b64encode(signature);
                returnStr = base64Signature;// java.net.URLEncoder.encode(base64Signature,
                                            // "UTF-8");
            }
            // catch (UnsupportedEncodingException ue) {
            // // TODO Auto-generated catch block
            // System.out.println(ue.getMessage());
            // }
            catch (Exception e) {
                System.out.println(e);
            }
            return returnStr;
        }

        public boolean Verify(String base64signature, String user, String time,
                String EncodedCert) {
            String toBeSigned = user + time;
            // try {
            // base64signature = java.net.URLDecoder.decode(base64signature,
            // "UTF-8");
            // } catch (UnsupportedEncodingException e) {
            // // TODO Auto-generated catch block
            // e.printStackTrace();
            // }
            byte[] signature = b64decode(base64signature);
            return verifySignature(signature, toBeSigned.getBytes(), EncodedCert);
        }

        /**
         * Generates the keys for given size.
         * 
         * @param size
         *            Key Size [512|1024]
         * @param privateKeyPath
         *            Private key will be generated in file which can be named with
         *            "privateKeyPath" parameter;
         * @param publicKeyPath
         *            Public key will be generated in file which can be named with
         *            "publicKeyPath" parameter;
         * @param netPublicKeyPath
         *            Public key can be read for .Net platform will be generated in
         *            file which can be named with "netPublicKeyPath" parameter;
         */
        public void GenerateKeys(int size, String privateKeyPath,
                String publicKeyPath, String netPublicKeyPath,
                String netPrivateKeyPath) {
            try {
                System.out.println("Generatign Keys");
                // Get Key Pair Generator for RSA.
                keyGen = KeyPairGenerator.getInstance("RSA");
                keyGen.initialize(size);
                keypair = keyGen.genKeyPair();
                privateKey = keypair.getPrivate();
                publicKey = keypair.getPublic();

                // Get the bytes of the public and private keys
                byte[] privateKeyBytes = privateKey.getEncoded();
                byte[] publicKeyBytes = publicKey.getEncoded();

                // write bytes to corresponding files.
                writeKeyBytesToFile(b64encode(privateKeyBytes).getBytes(),
                        privateKeyPath);
                String encodedValue = b64encode(publicKeyBytes);
                writeKeyBytesToFile(encodedValue.getBytes(), publicKeyPath);

                // Generate the Private Key, Public Key and Public Key in XML
                // format.
                PrivateKey privateKey = KeyFactory.getInstance("RSA")
                        .generatePrivate(new PKCS8EncodedKeySpec(privateKeyBytes));
                PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(
                        new X509EncodedKeySpec(publicKeyBytes));
                // RSAPublicKey rsaPublicKey = (RSAPublicKey)
                // KeyFactory.getInstance(
                // "RSA").generatePublic(
                // new X509EncodedKeySpec(publicKeyBytes));
                // // get the modules and exponent of public key to make compatible
                // // .Net public key file
                // String netPublicKey = getRSAPublicKeyAsNetFormat(rsaPublicKey);
                // Store the modules and exponent (Generated .Net public key file)
                // in file
                // writeKeyBytesToFile(netPublicKey.getBytes(), netPublicKeyPath);

                String netPrivateKey = getRSAPrivateKeyAsNetFormat(privateKeyBytes);
                writeKeyBytesToFile(netPrivateKey.getBytes(), netPrivateKeyPath);

                String netPublicKey = getRSAPublicKeyAsNetFormat(privateKeyBytes);
                writeKeyBytesToFile(netPublicKey.getBytes(), netPublicKeyPath);

            } catch (java.security.NoSuchAlgorithmException e) {
                System.out
                        .println("No such algorithm. Please check the JDK version."
                                + e.getCause());
            } catch (java.security.spec.InvalidKeySpecException ik) {
                System.out.println("Invalid Key Specs. Not valid Key files."
                        + ik.getCause());
            } catch (UnsupportedEncodingException ex) {
                System.out.println(ex);
            } catch (IOException ioe) {
                System.out.println("Files not found on specified path. "
                        + ioe.getCause());
            } catch (Exception ex1) {
                System.out.println(ex1);
            }

        }

        /**
         * Initialize only the private key.
         */
        private void initializePrivateKey(String privateKeyStr) {
            try {
                // Read key files back and decode them from BASE64
                byte[] privateKeyBytes = b64decode(privateKeyStr);

                // Convert back to public and private key objects
                KeyFactory keyFactory = KeyFactory.getInstance("RSA");
                EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(
                        privateKeyBytes);
                privateKey = keyFactory.generatePrivate(privateKeySpec);
            } catch (InvalidKeySpecException e) {
                System.out.println("Invalid Key Specs. Not valid Key files."
                        + e.getCause());
            } catch (NoSuchAlgorithmException e) {
                System.out
                        .println("There is no such algorithm. Please check the JDK ver."
                                + e.getCause());
            }
        }

        /**
         * Signs the data and return the signature for a given data.
         * 
         * @param toBeSigned
         *            Data to be signed
         * @return byte[] Signature
         */
        private byte[] signData(byte[] toBeSigned, String EncodedCert) {
            if (privateKey == null) {
                initializePrivateKey(EncodedCert);
            }
            try {
                Signature rsa = Signature.getInstance("SHA1withRSA");
                rsa.initSign(privateKey);
                rsa.update(toBeSigned);
                return rsa.sign();
            } catch (NoSuchAlgorithmException ex) {
                System.out.println(ex);
            } catch (InvalidKeyException in) {
                System.out
                        .println("Invalid Key file.Please check the key file path"
                                + in.getCause());
            } catch (SignatureException se) {
                System.out.println(se);
            }
            return null;
        }

        /**
         * Verifies the signature for the given bytes using the public key.
         * 
         * @param signature
         *            Signature
         * @param data
         *            Data that was signed
         * @param EncodedCert
         *            public key string
         * @return boolean True if valid signature else false
         */
        private boolean verifySignature(byte[] signature, byte[] data,
                String EncodedCert) {
            try {
                initializePublicKey(EncodedCert);
                sign.initVerify(publicKey);
                sign.update(data);
                return sign.verify(signature);
            } catch (SignatureException e) {
                e.printStackTrace();
            } catch (InvalidKeyException e) {
            }

            return false;
        }

        /**
         * Initializes the public and private keys.
         */
        private void initializePublicKey(String publicKeyStr) {
            try {
                // Read key files back and decode them from BASE64
                byte[] publicKeyBytes = b64decode(publicKeyStr);

                // Convert back to public and private key objects
                KeyFactory keyFactory = KeyFactory.getInstance("RSA");

                EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(
                        publicKeyBytes);
                publicKey = keyFactory.generatePublic(publicKeySpec);

            } catch (InvalidKeySpecException e) {
                System.out.println("Invalid Key Specs. Not valid Key files."
                        + e.getCause());
            } catch (NoSuchAlgorithmException e) {
                System.out
                        .println("There is no such algorithm. Please check the JDK ver."
                                + e.getCause());
            }
        }

    //    /**
    //     * Gets the RSA Public Key. The key idea is to make the key readable for
    //     * .Net platform.
    //     * 
    //     * @param key
    //     *            RSAPublicKey
    //     * @return String the public key that .Net platform can read
    //     */
    //    private String getRSAPublicKeyAsNetFormat(RSAPublicKey key) {
    //
    //        byte[] modulusBytes = key.getModulus().toByteArray();
    //        modulusBytes = stripLeadingZeros(modulusBytes);
    //        String modules = b64encode(modulusBytes);
    //
    //        byte[] exponentBytes = key.getPublicExponent().toByteArray();
    //        String exponent = b64encode(exponentBytes);
    //
    //        String result = "modules : " + modules + " " + "exponent : "
    //                + exponent;
    //        return result;
    //    }

        /**
         * Utility method to delete the leading zeros from the modulus.
         * 
         * @param a
         *            modulus
         * @return modulus
         */
        private byte[] stripLeadingZeros(byte[] a) {
            int lastZero = -1;
            for (int i = 0; i < a.length; i++) {
                if (a[i] == 0) {
                    lastZero = i;
                } else {
                    break;
                }
            }
            lastZero++;
            byte[] result = new byte[a.length - lastZero];
            System.arraycopy(a, lastZero, result, 0, result.length);
            return result;
        }

        /**
         * Writes the bytes of the key in a file.
         * 
         * @param key
         *            byte array of key data.
         * @param file
         *            File Name
         */
        private void writeKeyBytesToFile(byte[] key, String file)
                throws IOException {
            OutputStream out = new FileOutputStream(file);
            out.write(key);
            out.close();
        }

        // --- Returns XML encoded RSA private key string suitable for .NET
        // CryptoServiceProvider.FromXmlString(true) ------
        // --- Leading zero bytes (most significant) must be removed for XML
        // encoding for .NET; otherwise format error ---

        private String getRSAPrivateKeyAsNetFormat(byte[] encodedPrivkey) {
            try {
                StringBuffer buff = new StringBuffer(1024);

                PKCS8EncodedKeySpec pvkKeySpec = new PKCS8EncodedKeySpec(
                        encodedPrivkey);
                KeyFactory keyFactory = KeyFactory.getInstance("RSA");
                RSAPrivateCrtKey pvkKey = (RSAPrivateCrtKey) keyFactory
                        .generatePrivate(pvkKeySpec);

                buff.append("<RSAKeyValue>");
                buff.append("<Modulus>"
                        + b64encode(removeMSZero(pvkKey.getModulus().toByteArray()))
                        + "</Modulus>");

                buff.append("<Exponent>"
                        + b64encode(removeMSZero(pvkKey.getPublicExponent()
                                .toByteArray())) + "</Exponent>");

                buff.append("<P>"
                        + b64encode(removeMSZero(pvkKey.getPrimeP().toByteArray()))
                        + "</P>");

                buff.append("<Q>"
                        + b64encode(removeMSZero(pvkKey.getPrimeQ().toByteArray()))
                        + "</Q>");

                buff.append("<DP>"
                        + b64encode(removeMSZero(pvkKey.getPrimeExponentP()
                                .toByteArray())) + "</DP>");

                buff.append("<DQ>"
                        + b64encode(removeMSZero(pvkKey.getPrimeExponentQ()
                                .toByteArray())) + "</DQ>");

                buff.append("<InverseQ>"
                        + b64encode(removeMSZero(pvkKey.getCrtCoefficient()
                                .toByteArray())) + "</InverseQ>");

                buff.append("<D>"
                        + b64encode(removeMSZero(pvkKey.getPrivateExponent()
                                .toByteArray())) + "</D>");
                buff.append("</RSAKeyValue>");

                return buff.toString().replaceAll("[  ]", "");
            } catch (Exception e) {
                System.err.println(e);
                return null;
            }
        }

        // --- Returns XML encoded RSA public key string suitable for .NET
        // CryptoServiceProvider.FromXmlString(true) ------
        // --- Leading zero bytes (most significant) must be removed for XML
        // encoding for .NET; otherwise format error ---

        private String getRSAPublicKeyAsNetFormat(byte[] encodedPrivkey) {
            try {
                StringBuffer buff = new StringBuffer(1024);

                PKCS8EncodedKeySpec pvkKeySpec = new PKCS8EncodedKeySpec(
                        encodedPrivkey);
                KeyFactory keyFactory = KeyFactory.getInstance("RSA");
                RSAPrivateCrtKey pvkKey = (RSAPrivateCrtKey) keyFactory
                        .generatePrivate(pvkKeySpec);
                buff.append("<RSAKeyValue>");
                buff.append("<Modulus>"
                        + b64encode(removeMSZero(pvkKey.getModulus().toByteArray()))
                        + "</Modulus>");
                buff.append("<Exponent>"
                        + b64encode(removeMSZero(pvkKey.getPublicExponent()
                                .toByteArray())) + "</Exponent>");
                buff.append("</RSAKeyValue>");
                return buff.toString().replaceAll("[  ]", "");
            } catch (Exception e) {
                System.err.println(e);
                return null;
            }
        }

        // --------- remove leading (Most Significant) zero byte if present
        // ----------------
        private byte[] removeMSZero(byte[] data) {
            byte[] data1;
            int len = data.length;
            if (data[0] == 0) {
                data1 = new byte[data.length - 1];
                System.arraycopy(data, 1, data1, 0, len - 1);
            } else
                data1 = data;

            return data1;
        }

        private String b64encode(byte[] data) {

            String b64str = new String(Base64Encoder.encode(data));
            return b64str;
        }

        private byte[] b64decode(String data) {
            byte[] decodeData = Base64Decoder.decode(data);
            return decodeData;
        }

        public static void main(String args[]) {
            ssosign sso = new ssosign();
    //         sso.GenerateKeys(
    //         1024,
    //         "d:/private.key",
    //         "d:/public.key",
    //         "d:/netpublic.key",
    //         "d:/netprivate.key");

             String signedData = sso
             .Sign("zhangxn",
             "2010-12-10 11:21:18",
             "MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBAL6VJN4ZkfZA3aPPgKC3xaqT/yZT5FOlQ5TGg6heVqDVEHHVLH1E+HEEmWmuTv2ngz9pZbzy9KWkJpV59W1dgNHSSk575VjUAv0BhZXFSH0lng2mZ2Q5/2dVxKsASjJ2bQiEGUD8LO5KpaLlfQpo3ANovBZvUtHw5exegnyXyZbDAgMBAAECgYEAr7YEWr1KhLcDYg9jMUqd9QokOSspnTEGoPlx016/EeO/GKSJMynOwSyTYQszisvRxzoecdmyU7GHXVMnQ2Ds7WvbcuNkIRWmxFa4nTkk2zNF6KByvvFwLiW4LQXF6B+uV7+ZNqvfhCoD/j2wki8jfWkuuAaKnTda/axHMi+zRYECQQD73iC2GjZyur4amJQPK6d+kDlJ0dYyyUvQa0vd6mfoPnQDOIqayBaueSwWIpLI/L7eUuP9CDFryQtdBvWqD/dBAkEAwbWcrybn0eaxiPZacZLZXzXO8g12hYoXT1h0DTLvy1rnVUOspNfKZcBZMjPxT4+QEknoTShSnSbJ5sHitfZxAwJBANMlU2z2KqEh1k77jFvvb9oVVEGDbTtkL2+JE6/1W6iB+sXcd63sgb9Ai+n+j+l4oRZGjSTJ4oyGnUUemYI5IkECQQCA9JNrcv4PGYIFCOPrCfTV0m+Dan0Fp4mfE+amRsumWEz60UOktdeS53s51aSG767czgDtJLPi1MjCaz6vHnHbAkEA4NxLLg6UCAoCpXMgqqZHWMgbMwNNFr9diCWP/tZ5OJmWYHgn7zfqMXa/RNaethjdG1biIkj5h7qm6XDBBqGuxw==");
             System.out.println(signedData);

    //        String signedData = "D+vkrMIe9cJyr3kELI5jNes/bJe7MLExyJDMqJyBlVgFtmPNQ723IsBtWmqO93yoBoKHaxeTI1kwaJzESe3X5vqS6TfFBTl+IeX5aJ/cc1+Hxo5Rr2QZwzUywgS/e3gRC+Ik+Fx0M0gBaQTGNdIDNaIvl776+0SNVaD0L3Sar9k=";
    //        boolean res = sso
    //                .Verify(signedData,
    //                        "zhangxn",
    //                        "2010-12-10 11:21:18",
    //                        "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDWWmcu+6YPz8150nuzhZLxQ7045FtdVOAleZ9rvZsjgDUvWXo2n3UERND7IHwWrqIZbDk5Hw4HZRtEFyilvZ616kOpZ3uSYK1tVPfqRNb4Tx1Z1pWNsjYEJcQZpe7M890Y6WnnY5prBhHnPIbQyIK8niMTtEMlrHgKXbhmo9SzhQIDAQAB");
    //        System.out.println(res);

        }
  • 相关阅读:
    PAT A1017 Queueing at Bank [硬核模拟]
    PAT A1105 Spiral Matrix [硬核模拟]
    PAT A1153 Decode Registration Card of PAT [排序模拟]
    PAT A1139 First Contact [图]
    jquery的animate动画
    wordpress建站过程5——footer.php
    wordpress建站过程4——index.php
    wordpress建站过程3——header.php
    HTML中加载flash方法
    轮播图的原理
  • 原文地址:https://www.cnblogs.com/Alex80/p/11526655.html
Copyright © 2020-2023  润新知