JAVA RSA加解密和数字签名、DES加解密 在项目中的实际使用

    xiaoxiao2021-03-26  35

    RSA: 1、生成随机秘钥对 2、用公钥加密私钥解密  客户端:RSA用公钥加密之后,需要对加密后的数据在进行Base64加密, 以便在HTTP协议之间传输(兼容各语言的差异性)。 服务端:以JAVA端为列,接受到数据流(InputStream)之后,将流转化为字符串,先用Base64解密,将解密后的结果,在用RSA的私钥解密。 PS:公钥保存在客户端,私钥保存在服务器端。 如果需要加解密的,采用公钥加密,私钥解密的流程。

    私钥加密,一般用来做数字签名,然后用公钥来验证改数字签名。

    [java]  view plain  copy   import java.io.BufferedReader;    import java.io.BufferedWriter;    import java.io.FileReader;    import java.io.FileWriter;    import java.io.IOException;    import java.security.InvalidKeyException;    import java.security.KeyFactory;    import java.security.KeyPair;    import java.security.KeyPairGenerator;    import java.security.NoSuchAlgorithmException;    import java.security.SecureRandom;        import java.security.interfaces.RSAPrivateKey;    import java.security.interfaces.RSAPublicKey;    import java.security.spec.InvalidKeySpecException;    import java.security.spec.PKCS8EncodedKeySpec;    import java.security.spec.X509EncodedKeySpec;        import javax.crypto.BadPaddingException;    import javax.crypto.Cipher;    import javax.crypto.IllegalBlockSizeException;    import javax.crypto.NoSuchPaddingException;       import sun.misc.BASE64Decoder;   import sun.misc.BASE64Encoder;              public class RSAEncrypt {        /**       * 字节数据转字符串专用集合       */        private static final char[] HEX_CHAR = { '0''1''2''3''4''5''6',                '7''8''9''a''b''c''d''e''f' };            /**       * 随机生成密钥对       */        public static void genKeyPair(String filePath) {            // KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象            KeyPairGenerator keyPairGen = null;            try {                keyPairGen = KeyPairGenerator.getInstance("RSA");            } catch (NoSuchAlgorithmException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }            // 初始化密钥对生成器,密钥大小为96-1024位            keyPairGen.initialize(1024,new SecureRandom());            // 生成一个密钥对,保存在keyPair中            KeyPair keyPair = keyPairGen.generateKeyPair();            // 得到私钥            RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();            // 得到公钥            RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();            try {                // 得到公钥字符串                String publicKeyString = new String(encryptBASE64(publicKey.getEncoded()));                // 得到私钥字符串                String privateKeyString =new String(encryptBASE64(privateKey.getEncoded()));                // 将密钥对写入到文件                FileWriter pubfw = new FileWriter(filePath + "/publicKey.keystore");                FileWriter prifw = new FileWriter(filePath + "/privateKey.keystore");                BufferedWriter pubbw = new BufferedWriter(pubfw);                BufferedWriter pribw = new BufferedWriter(prifw);                pubbw.write(publicKeyString);                pribw.write(privateKeyString);                pubbw.flush();                pubbw.close();                pubfw.close();                pribw.flush();                pribw.close();                prifw.close();            } catch (Exception e) {                e.printStackTrace();            }        }            /**       * 从文件中输入流中加载公钥       *        * @param in       *            公钥输入流       * @throws Exception       *             加载公钥时产生的异常       */        public static String loadPublicKeyByFile(String path) throws Exception {            try {                BufferedReader br = new BufferedReader(new FileReader(path                        + "/publicKey.keystore"));                String readLine = null;                StringBuilder sb = new StringBuilder();                while ((readLine = br.readLine()) != null) {                    sb.append(readLine);                }                br.close();                return sb.toString();            } catch (IOException e) {                throw new Exception("公钥数据流读取错误");            } catch (NullPointerException e) {                throw new Exception("公钥输入流为空");            }        }            /**       * 从字符串中加载公钥       *        * @param publicKeyStr       *            公钥数据字符串       * @throws Exception       *             加载公钥时产生的异常       */        public static RSAPublicKey loadPublicKeyByStr(String publicKeyStr)                throws Exception {            try {                byte[] buffer = decryptBASE64(publicKeyStr);                KeyFactory keyFactory = KeyFactory.getInstance("RSA");                X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);                return (RSAPublicKey) keyFactory.generatePublic(keySpec);            } catch (NoSuchAlgorithmException e) {                throw new Exception("无此算法");            } catch (InvalidKeySpecException e) {                throw new Exception("公钥非法");            } catch (NullPointerException e) {                throw new Exception("公钥数据为空");            }        }            /**       * 从文件中加载私钥       *        * @param keyFileName       *            私钥文件名       * @return 是否成功       * @throws Exception       */        public static String loadPrivateKeyByFile(String path) throws Exception {            try {                BufferedReader br = new BufferedReader(new FileReader(path                        + "/privateKey.keystore"));                String readLine = null;                StringBuilder sb = new StringBuilder();                while ((readLine = br.readLine()) != null) {                    sb.append(readLine);                }                br.close();                return sb.toString();            } catch (IOException e) {                throw new Exception("私钥数据读取错误");            } catch (NullPointerException e) {                throw new Exception("私钥输入流为空");            }        }            public static RSAPrivateKey loadPrivateKeyByStr(String privateKeyStr)                throws Exception {            try {                byte[] buffer = decryptBASE64(privateKeyStr);                PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);                KeyFactory keyFactory = KeyFactory.getInstance("RSA");                return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);            } catch (NoSuchAlgorithmException e) {                throw new Exception("无此算法");            } catch (InvalidKeySpecException e) {                throw new Exception("私钥非法");            } catch (NullPointerException e) {                throw new Exception("私钥数据为空");            }        }            /**       * 公钥加密过程       *        * @param publicKey       *            公钥       * @param plainTextData       *            明文数据       * @return       * @throws Exception       *             加密过程中的异常信息       */        public static byte[] encrypt(RSAPublicKey publicKey, byte[] plainTextData)                throws Exception {            if (publicKey == null) {                throw new Exception("加密公钥为空, 请设置");            }            Cipher cipher = null;            try {                // 使用默认RSA                cipher = Cipher.getInstance("RSA");                // cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());                cipher.init(Cipher.ENCRYPT_MODE, publicKey);                byte[] output = cipher.doFinal(plainTextData);                return output;            } catch (NoSuchAlgorithmException e) {                throw new Exception("无此加密算法");            } catch (NoSuchPaddingException e) {                e.printStackTrace();                return null;            } catch (InvalidKeyException e) {                throw new Exception("加密公钥非法,请检查");            } catch (IllegalBlockSizeException e) {                throw new Exception("明文长度非法");            } catch (BadPaddingException e) {                throw new Exception("明文数据已损坏");            }        }            /**       * 私钥加密过程       *        * @param privateKey       *            私钥       * @param plainTextData       *            明文数据       * @return       * @throws Exception       *             加密过程中的异常信息       */        public static byte[] encrypt(RSAPrivateKey privateKey, byte[] plainTextData)                throws Exception {            if (privateKey == null) {                throw new Exception("加密私钥为空, 请设置");            }            Cipher cipher = null;            try {                // 使用默认RSA                cipher = Cipher.getInstance("RSA");                cipher.init(Cipher.ENCRYPT_MODE, privateKey);                byte[] output = cipher.doFinal(plainTextData);                return output;            } catch (NoSuchAlgorithmException e) {                throw new Exception("无此加密算法");            } catch (NoSuchPaddingException e) {                e.printStackTrace();                return null;            } catch (InvalidKeyException e) {                throw new Exception("加密私钥非法,请检查");            } catch (IllegalBlockSizeException e) {                throw new Exception("明文长度非法");            } catch (BadPaddingException e) {                throw new Exception("明文数据已损坏");            }        }            /**       * 私钥解密过程       *        * @param privateKey       *            私钥       * @param cipherData       *            密文数据       * @return 明文       * @throws Exception       *             解密过程中的异常信息       */        public static byte[] decrypt(RSAPrivateKey privateKey, byte[] cipherData)                throws Exception {            if (privateKey == null) {                throw new Exception("解密私钥为空, 请设置");            }            Cipher cipher = null;            try {                // 使用默认RSA                cipher = Cipher.getInstance("RSA");                // cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());                cipher.init(Cipher.DECRYPT_MODE, privateKey);                byte[] output = cipher.doFinal(cipherData);                return output;            } catch (NoSuchAlgorithmException e) {                throw new Exception("无此解密算法");            } catch (NoSuchPaddingException e) {                e.printStackTrace();                return null;            } catch (InvalidKeyException e) {                throw new Exception("解密私钥非法,请检查");            } catch (IllegalBlockSizeException e) {                throw new Exception("密文长度非法");            } catch (BadPaddingException e) {                throw new Exception("密文数据已损坏");            }        }            /**       * 公钥解密过程       *        * @param publicKey       *            公钥       * @param cipherData       *            密文数据       * @return 明文       * @throws Exception       *             解密过程中的异常信息       */        public static byte[] decrypt(RSAPublicKey publicKey, byte[] cipherData)                throws Exception {            if (publicKey == null) {                throw new Exception("解密公钥为空, 请设置");            }            Cipher cipher = null;            try {                // 使用默认RSA                cipher = Cipher.getInstance("RSA");                // cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());                cipher.init(Cipher.DECRYPT_MODE, publicKey);                byte[] output = cipher.doFinal(cipherData);                return output;            } catch (NoSuchAlgorithmException e) {                throw new Exception("无此解密算法");            } catch (NoSuchPaddingException e) {                e.printStackTrace();                return null;            } catch (InvalidKeyException e) {                throw new Exception("解密公钥非法,请检查");            } catch (IllegalBlockSizeException e) {                throw new Exception("密文长度非法");            } catch (BadPaddingException e) {                throw new Exception("密文数据已损坏");            }        }            /**       * 字节数据转十六进制字符串       *        * @param data       *            输入数据       * @return 十六进制内容       */        public static String byteArrayToString(byte[] data) {            StringBuilder stringBuilder = new StringBuilder();            for (int i = 0; i < data.length; i++) {                // 取出字节的高四位 作为索引得到相应的十六进制标识符 注意无符号右移                stringBuilder.append(HEX_CHAR[(data[i] & 0xf0) >>> 4]);                // 取出字节的低四位 作为索引得到相应的十六进制标识符                stringBuilder.append(HEX_CHAR[(data[i] & 0x0f)]);                if (i < data.length - 1) {                    stringBuilder.append(' ');                }            }            return stringBuilder.toString();        }               public static String encryptBASE64(byte[] key) throws Exception {             return (new BASE64Encoder()).encodeBuffer(key);        }        public static byte[] decryptBASE64(String key) throws Exception {             return (new BASE64Decoder()).decodeBuffer(key);        }      }    

    上面代码中,利用 genKeyPair ()方法来生成钥匙对。 加密: RSAEncrypt. encryptBASE64 (RSAEncrypt. encrypt (RSAEncrypt. loadPublicKeyByStr (RSAEncrypt. loadPublicKeyByFile (filepath)),"要加密的字符串".getBytes())) 解密: RSAEncrypt. decrypt (RSAEncrypt. loadPrivateKeyByStr (RSAEncrypt. loadPrivateKeyByFile (filepath)), RSAEncrypt. decryptBASE64 ("要解密的字符串")) 下面用 私钥加密(数字签名),用公钥进行验证 [java]  view plain  copy           System. out.println( "---------------私钥签名过程------------------" );            String content= "ihep_这是用于签名的原始数据" ;            String signstr=RSASignature.encryptBASE64(RSASignature. sign(content,RSAEncrypt.loadPrivateKeyByFile(filepath)));            System. out.println( "签名原串:" +content);            System. out.println( "签名串:"+signstr);            System. out.println();    //                    System. out.println( "---------------公钥校验签名------------------" );            System. out.println( "签名原串:" +content);            System. out.println( "签名串:"+signstr);                        System. out. println("验签结果:"+RSASignature. doCheck(content, signstr, RSAEncrypt.loadPublicKeyByFile(filepath)));   输出结果:

    附上签名的class:

    [java]  view plain  copy       import java.security.KeyFactory;    import java.security.PrivateKey;    import java.security.PublicKey;    import java.security.spec.PKCS8EncodedKeySpec;    import java.security.spec.X509EncodedKeySpec;          import sun.misc.BASE64Decoder;   import sun.misc.BASE64Encoder;               /**  * RSA签名验签类  */    public class RSASignature{                /**       * 签名算法       */        public static final String SIGN_ALGORITHMS = "SHA1WithRSA";    //    public static final String SIGN_ALGORITHMS = "sha1WithRSAEncryption";            /**      * RSA签名      * @param content 待签名数据      * @param privateKey 商户私钥      * @param encode 字符集编码      * @return 签名值      */        public static String sign(String content, String privateKey, String encode)        {            try             {                PKCS8EncodedKeySpec priPKCS8    = new PKCS8EncodedKeySpec(decryptBASE64(privateKey) );                                 KeyFactory keyf                 = KeyFactory.getInstance("RSA");                PrivateKey priKey               = keyf.generatePrivate(priPKCS8);                    java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);                    signature.initSign(priKey);                signature.update( content.getBytes(encode));                    byte[] signed = signature.sign();                                return new String( encryptBASE64(signed));            }            catch (Exception e)             {                e.printStackTrace();            }                        return null;        }                public static byte[] sign(String content, String privateKey)        {            try             {                PKCS8EncodedKeySpec priPKCS8    = new PKCS8EncodedKeySpec( decryptBASE64(privateKey) );                 KeyFactory keyf = KeyFactory.getInstance("RSA");                PrivateKey priKey = keyf.generatePrivate(priPKCS8);                java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);                signature.initSign(priKey);                signature.update( content.getBytes());                byte[] signed = signature.sign();                return signed;            }            catch (Exception e)             {                e.printStackTrace();            }            return null;        }                /**      * RSA验签名检查      * @param content 待签名数据      * @param sign 签名值      * @param publicKey 分配给开发商公钥      * @param encode 字符集编码      * @return 布尔值      */        public static boolean doCheck(String content, String sign, String publicKey,String encode)        {            try             {                KeyFactory keyFactory = KeyFactory.getInstance("RSA");                byte[] encodedKey =decryptBASE64(publicKey);                PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));                                java.security.Signature signature = java.security.Signature                .getInstance(SIGN_ALGORITHMS);                            signature.initVerify(pubKey);                signature.update( content.getBytes(encode) );                            boolean bverify = signature.verify( decryptBASE64(sign) );                return bverify;                            }             catch (Exception e)             {                e.printStackTrace();            }                        return false;        }                public static boolean doCheck(String content, String sign, String publicKey)        {            try             {                KeyFactory keyFactory = KeyFactory.getInstance("RSA");                byte[] encodedKey =decryptBASE64(publicKey);                PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));                                java.security.Signature signature = java.security.Signature                .getInstance(SIGN_ALGORITHMS);                            signature.initVerify(pubKey);                signature.update( content.getBytes() );                            boolean bverify = signature.verify(decryptBASE64(sign) );                return bverify;                            }             catch (Exception e)             {                e.printStackTrace();            }                        return false;        }         public static String encryptBASE64(byte[] key) throws Exception {             return (new BASE64Encoder()).encodeBuffer(key);        }        public static byte[] decryptBASE64(String key) throws Exception {             return (new BASE64Decoder()).decodeBuffer(key);        }          }   

    DES加解密: 1、客户端:首先进行DES加密,再将加密后的结果进行BASE64加密。 2、服务端:将得到的流转化为字符串,在进行BASE64解密, 将解密之后的结果再进行DES解密。 DES加解密的KEY必须一致! [java]  view plain  copy   package des;      import java.net.URLDecoder;   import java.net.URLEncoder;   import java.security.SecureRandom;      import javax.crypto.Cipher;   import javax.crypto.SecretKey;   import javax.crypto.SecretKeyFactory;   import javax.crypto.spec.DESKeySpec;      import com.alibaba.fastjson.JSONObject;      import sun.misc.BASE64Decoder;   import sun.misc.BASE64Encoder;      public class EncryptUtil {               public static final String DES_KEY="@Wx^t)V#";           /**       *       * 解密       *       * @param src       *            数据源       * @param key       *            密钥,长度必须是8的倍数       * @return 返回解密后的原始数据       * @throws Exception       */        public static byte[] decrypt(byte[] src, byte[] key) throws Exception {             // DES算法要求有一个可信任的随机数源             SecureRandom sr = new SecureRandom();             // 从原始密匙数据创建一个DESKeySpec对象             DESKeySpec dks = new DESKeySpec(key);             // 创建一个密匙工厂,然后用它把DESKeySpec对象转换成             // 一个SecretKey对象             SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");             SecretKey securekey = keyFactory.generateSecret(dks);             // Cipher对象实际完成解密操作             Cipher cipher = Cipher.getInstance("DES");             // 用密匙初始化Cipher对象             cipher.init(Cipher.DECRYPT_MODE, securekey, sr);             // 现在,获取数据并解密             // 正式执行解密操作             return cipher.doFinal(src);        }           /**       *       * 加密       *       * @param src       *            数据源       *       * @param key       *            密钥,长度必须是8的倍数       *       * @return 返回加密后的数据       *       * @throws Exception       *       */        public static byte[] encrypt(byte[] src, byte[] key) throws Exception {             // DES算法要求有一个可信任的随机数源             SecureRandom sr = new SecureRandom();             // 从原始密匙数据创建DESKeySpec对象             DESKeySpec dks = new DESKeySpec(key);             // 创建一个密匙工厂,然后用它把DESKeySpec转换成             // 一个SecretKey对象             SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");             SecretKey securekey = keyFactory.generateSecret(dks);             // Cipher对象实际完成加密操作             Cipher cipher = Cipher.getInstance("DES");             // 用密匙初始化Cipher对象             cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);             // 现在,获取数据并加密             // 正式执行加密操作             return cipher.doFinal(src);        }        public static String encryptBASE64(byte[] key) throws Exception {             return (new BASE64Encoder()).encodeBuffer(key);        }        public static byte[] decryptBASE64(String key) throws Exception {             return (new BASE64Decoder()).decodeBuffer(key);        }               @SuppressWarnings("deprecation")        public static void main(String[] args) throws Exception {             JSONObject obj= new JSONObject();             obj.put("name""张三");             System.out.println("加密前的数据:"+obj.toString());             System.out.println("DES开始加密......");                         String enData=encryptBASE64(encrypt(obj.toString().getBytes(), DES_KEY.getBytes()));             System.out.println("加密后的数据"+enData);                         System.out.println("DES开始解密.....");             String deData=new String(decrypt(decryptBASE64(enData), DES_KEY.getBytes()));             System.out.println("DES解密后的数据:"+deData);        }   }   输入结果: 加密前的数据:{"name":"张三"} DES开始加密...... 加密后的数据cOOCD8/CXRmjaBYA5K7KYA== DES开始解密..... DES解密后的数据:{"name":"张三"}
    转载请注明原文地址: https://ju.6miu.com/read-662769.html

    最新回复(0)