私钥加密,一般用来做数字签名,然后用公钥来验证改数字签名。
[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":"张三"}
