java加密解密算法记录
以下内容均摘自我买的书籍《java加密与解密的艺术》作者 梁栋
package com.algorithm; import java.security.Key; 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.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.HashMap; import java.util.Map; import javax.crypto.Cipher; import org.apache.commons.codec.binary.Hex; /** * RSA非对称加密算法安全编码组件 * @author Administrator * */ public abstract class RSACoder { //非对称加密密钥算法 public static final String KEY_ALGORITHM="RSA"; //数字签名 签名/验证算法 public static final String SIGNATURE_ALGORRITHM="SHA1withRSA"; //公钥 private static final String PUBLIC_KEY="RSAPublicKey"; //私钥 private static final String PRIVATE_KEY="RSAPrivateKey"; //RSA密钥长度,默认为1024,密钥长度必须是64的倍数,范围在521~65526位之间 private static final int KEY_SIZE=512; /** * 私钥解密 * @param data 待解密数据 * @param key 私钥 * @return byte[] 解密数据 * @throws Exception */ public static byte[] decryptByPrivateKey(byte[] data,byte[]key) throws Exception { //取得私钥 PKCS8EncodedKeySpec pkcs8KeySpec=new PKCS8EncodedKeySpec(key); KeyFactory keyFactory=KeyFactory.getInstance(KEY_ALGORITHM); //生成私钥 PrivateKey privateKey=keyFactory.generatePrivate(pkcs8KeySpec); //对数据解密 Cipher cipher=Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateKey); return cipher.doFinal(data); } /** * 私钥解密 * @param data 待解密数据 * @param key 私钥 * @return byte[] 解密数据 * @throws Exception */ public static byte[] decryptByPrivateKey(byte[] data,String privateKey) throws Exception { return decryptByPrivateKey(data,getKey(privateKey)); } /** * 公钥解密 * @param data 待解密数据 * @param key 公钥 * @return byte[] 解密数据 * @throws Exception */ public static byte[] decryptByPublicKey(byte[] data,byte[] key) throws Exception { //取得公钥 X509EncodedKeySpec x509KeySpec=new X509EncodedKeySpec(key); KeyFactory keyFactory=KeyFactory.getInstance(KEY_ALGORITHM); //生成公钥 PublicKey publicKey=keyFactory.generatePublic(x509KeySpec); //对数据解密 Cipher cipher=Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, publicKey); return cipher.doFinal(data); } /** * 公钥解密 * @param data 待解密数据 * @param key 公钥 * @return byte[] 解密数据 * @throws Exception */ public static byte[] decryptByPublicKey(byte[] data,String publicKey) throws Exception { return decryptByPublicKey(data,getKey(publicKey)); } /** * 公钥加密 * @param data 待加密数据 * @param key 公钥 * @return byte[] 加密数据 * @throws Exception */ public static byte[] encryptByPublicKey(byte[] data,byte[] key) throws Exception { //取得公钥 X509EncodedKeySpec x509KeySpec=new X509EncodedKeySpec(key); KeyFactory keyFactory=KeyFactory.getInstance(KEY_ALGORITHM); PublicKey publicKey=keyFactory.generatePublic(x509KeySpec); //对数据加密 Cipher cipher=Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicKey); return cipher.doFinal(data); } /** * 公钥加密 * @param data 待加密数据 * @param key 公钥 * @return byte[] 加密数据 * @throws Exception */ public static byte[] encryptByPublicKey(byte[] data,String publicKey) throws Exception { return encryptByPublicKey(data,getKey(publicKey)); } /** * 私钥加密 * @param data 待加密数据 * @param key 私钥 * @return byte[] 加密数据 * @throws Exception */ public static byte[] encryptByPrivateKey(byte[] data,byte[] key) throws Exception { //取得私钥 PKCS8EncodedKeySpec pkcs8KeySpec=new PKCS8EncodedKeySpec(key); KeyFactory keyFactory=KeyFactory.getInstance(KEY_ALGORITHM); //生成私钥 PrivateKey privateKey=keyFactory.generatePrivate(pkcs8KeySpec); //对数据加密 Cipher cipher=Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, privateKey); return cipher.doFinal(data); } /** * 私钥加密 * @param data 待加密数据 * @param key 私钥 * @return byte[] 加密数据 * @throws Exception */ public static byte[] encryptByPrivateKey(byte[] data,String key) throws Exception { return encryptByPrivateKey(data,getKey(key)); } /** * 取得私钥 * @param keyMap 密钥Map * @return byte[] 私钥 * @throws Exception */ public static byte[] getPrivateKey(Map<String,Object> keyMap) throws Exception { Key key=(Key)keyMap.get(PRIVATE_KEY); return key.getEncoded(); } /** * 取得公钥 * @param keyMap 密钥Map * @return byte[] 公钥 * @throws Exception */ public static byte[] getPublicKey(Map<String,Object> keyMap) throws Exception { Key key=(Key)keyMap.get(PUBLIC_KEY); return key.getEncoded(); } /** * 初始化密钥 * @return 密钥Map * @throws Exception */ public static Map<String,Object> initKey() throws Exception { //实例化实钥对生成器 KeyPairGenerator keyPairGen=KeyPairGenerator.getInstance(KEY_ALGORITHM); //初始化密钥对生成器 keyPairGen.initialize(KEY_SIZE); //生成密钥对 KeyPair keyPair=keyPairGen.generateKeyPair(); //公钥 RSAPublicKey publicKey=(RSAPublicKey) keyPair.getPublic(); //私钥 RSAPrivateKey privateKey=(RSAPrivateKey) keyPair.getPrivate(); //封装密钥 Map<String,Object> keyMap=new HashMap<String,Object>(2); keyMap.put(PUBLIC_KEY, publicKey); keyMap.put(PRIVATE_KEY, privateKey); return keyMap; } /** * 签名 * @param data 待签名数据 * @param privateKey 私钥 * @return byte[] 数字签名 * @throws Exception */ public static byte[] sign(byte[] data,byte[] privateKey) throws Exception { //转接私钥材料 PKCS8EncodedKeySpec pkcs8KeySpec=new PKCS8EncodedKeySpec(privateKey); //实例化密钥工厂 KeyFactory keyFactory=KeyFactory.getInstance(KEY_ALGORITHM); //取私钥对象 PrivateKey priKey=keyFactory.generatePrivate(pkcs8KeySpec); //实例化Signature Signature signature=Signature.getInstance(SIGNATURE_ALGORRITHM); //初始化Signature signature.initSign(priKey); //更新 signature.update(data); //签名 return signature.sign(); } /** * 公钥校验 * @param data 待校验数据 * @param publicKey 公钥 * @param sign 数字签名 * @return * @throws Exception */ public static boolean verify(byte[] data,byte[] publicKey,byte[] sign) throws Exception { //转接公钥材料 X509EncodedKeySpec x509KeySpec=new X509EncodedKeySpec(publicKey); //实例化密钥工厂 KeyFactory keyFactory=KeyFactory.getInstance(KEY_ALGORITHM); //生成公钥 PublicKey pubKey=keyFactory.generatePublic(x509KeySpec); //实例化Signature Signature signature=Signature.getInstance(SIGNATURE_ALGORRITHM); //初始化Signature signature.initVerify(pubKey); //更新 signature.update(data); //验证 return signature.verify(sign); } /** * 私钥签名 * @param data 待签名数据 * @param privateKey 私钥 * @return String 十六进制签名字符串 * @throws Exception */ public static String sign(byte[] data,String privateKey) throws Exception { byte[] sign=sign(data,getKey(privateKey)); return Hex.encodeHexString(sign); } /** * 公钥校验 * @param data 待验证数据 * @param publicKey 公钥 * @param sign 签名 * @return boolean 成功返回true,失败返回false * @throws Exception */ public static boolean verify(byte[] data,String publicKey,String sign) throws Exception { return verify(data,getKey(publicKey),Hex.decodeHex(sign.toCharArray())); } /** * 取得私钥十六进制表示形式 * @param keyMap 密钥Map * @return String 私钥十六进制字符串 * @throws Exception */ public static String getPrivateKeyString(Map<String,Object> keyMap) throws Exception { return Hex.encodeHexString(getPrivateKey(keyMap)); } /** * 取得公钥十六进制表示形式 * @param keyMap 密钥Map * @return String 公钥十六进制字符串 * @throws Exception */ public static String getPublicKeyString(Map<String,Object> keyMap) throws Exception { return Hex.encodeHexString(getPublicKey(keyMap)); } /** * 获取密钥 * @param key 密钥 * @return byte[] 密钥 * @throws Exception */ public static byte[] getKey(String key) throws Exception { return Hex.decodeHex(key.toCharArray()); } } package com.algorithm; import java.util.Map; import org.apache.commons.codec.binary.Base64; /** * RSA算法测试用例 * @author Administrator * */ public class RSACoderTest { //公钥 private static byte[] publicKey; //私钥 private static byte[] privateKey; /** * 初始化密钥 * @throws Exception */ public static void initKey() throws Exception { //初始化密钥 Map<String,Object> keyMap=RSACoder.initKey(); publicKey=RSACoder.getPublicKey(keyMap); privateKey=RSACoder.getPrivateKey(keyMap); System.out.println("公钥:"+Base64.encodeBase64String(publicKey)); System.out.println("私钥:"+Base64.encodeBase64String(privateKey)); } public static void test() throws Exception { String inputStr="RSA加密算法,私钥加密,公钥解密"; byte[] data=inputStr.getBytes(); //私钥加密 byte[] enCodeData=RSACoder.encryptByPrivateKey(data,privateKey); System.out.println("加密字符串:"+Base64.encodeBase64String(enCodeData)); //公钥解密 byte[] deCodeData=RSACoder.decryptByPublicKey(enCodeData, publicKey); System.out.println(new String(deCodeData).equals(inputStr)); } /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { // TODO Auto-generated method stub initKey(); RSACoderTest.test(); } } package com.algorithm; import java.io.FileInputStream; import java.security.KeyStore; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import javax.crypto.Cipher; /** * 证书组件 * @author Administrator */ public abstract class CertificateCoder { //类型证书 private static final String CERT_TYPE="X.509"; /** * 由KeyStore获得私钥 * @param keyStorePath 密钥库路径 * @param alias 别名 * @param password 密码 * @return PrivateKey 密钥 * @throws Exception */ private static PrivateKey getPrivateKeyByKeyStore(String keyStorePath,String alias,String password) throws Exception { //获得密钥库 KeyStore ks=getKeyStore(keyStorePath,password); //获得私钥 return (PrivateKey)ks.getKey(alias, password.toCharArray()); } /** * 由Certificate获得公钥 * @param certificatePath 证书路径 * @return PublicKey 公钥 */ private static PublicKey getPublicKeyByCertificate(String certificatePath) throws Exception { //获得证书 Certificate certificate=getCertificate(certificatePath); //获得公钥 return certificate.getPublicKey(); } /** * 获得certificate * @param certificatePath 证书路径 * @return Certificate 证书 * @throws Exception */ private static Certificate getCertificate(String certificatePath) throws Exception { //实例化证书工厂 CertificateFactory certificateFactory=CertificateFactory.getInstance(CERT_TYPE); //取得证书文件流 FileInputStream in=new FileInputStream(certificatePath); //生成证书 Certificate certificate=certificateFactory.generateCertificate(in); //关闭证书文件流 in.close(); return certificate; } /** * 取得Certificate * @param keyStorePath 密钥库路径 * @param alias 别名 * @param password 密码 * @return Certificate 证书 * @throws Exception */ private static Certificate getCertificate(String keyStorePath,String alias,String password) throws Exception { //获得密钥库 KeyStore ks=getKeyStore(keyStorePath,password); //获得证书 return ks.getCertificate(alias); } /** * 获得密钥库 * @param keyStorePath 密钥库路径 * @param password 密码 * @return KeyStore 密钥库 * @throws Exception */ private static KeyStore getKeyStore(String keyStorePath,String password) throws Exception { //实例化密钥库 KeyStore ks=KeyStore.getInstance(KeyStore.getDefaultType()); //获得密钥库文件流 FileInputStream in=new FileInputStream(keyStorePath); //加载密钥库 ks.load(in, password.toCharArray()); //关闭密钥库文件流 in.close(); return ks; } /** * 私钥加密 * @param data 待加密数据 * @param keyStorePath 密钥库路径 * @param alias 别名 * @param password 密码 * @return byte[] 加密数据 * @throws Exception */ public static byte[] encryptByPrivateKey(byte[] data,String keyStorePath,String alias,String password) throws Exception { //取得私钥 PrivateKey privateKey=getPrivateKeyByKeyStore(keyStorePath,alias,password); //对数据加密 Cipher cipher=Cipher.getInstance(privateKey.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, privateKey); return cipher.doFinal(data); } /** * 私钥解密 * @param data 待解密数据 * @param keyStorePath 密钥库路径 * @param alias 别名 * @param password 密码 * @return byte[] 加密数据 * @throws Exception */ public static byte[] decryptByPrivateKey(byte[] data,String keyStorePath,String alias,String password) throws Exception { //取得私钥 PrivateKey privateKey=getPrivateKeyByKeyStore(keyStorePath,alias,password); //对数据解密 Cipher cipher=Cipher.getInstance(privateKey.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateKey); return cipher.doFinal(data); } /** * 公钥加密 * @param data 待加密数据 * @param certificatePath 证书路径 * @return byte[] 加密数据 * @throws Exception */ public static byte[] encryptByPublicKey(byte[] data,String certificatePath) throws Exception { //取得公钥 PublicKey publicKey=getPublicKeyByCertificate(certificatePath); //对数据加密 Cipher cipher=Cipher.getInstance(publicKey.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicKey); return cipher.doFinal(data); } /** * 公钥解密 * @param data 待解密数据 * @param certificatePath 证书路径 * @return byte[] 解密数据 * @throws Exception */ public static byte[] decryptByPublicKey(byte[] data,String certificatePath) throws Exception { //取得公钥 PublicKey publicKey=getPublicKeyByCertificate(certificatePath); //对数据解密 Cipher cipher=Cipher.getInstance(publicKey.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, publicKey); return cipher.doFinal(data); } /** * 签名 * @param data 待签名数据 * @param keyStorePath 密钥库路径 * @param alias 别名 * @param password 密码 * @return byte[] 签名 * @throws Exception */ public static byte[] sign(byte[] data,String keyStorePath,String alias,String password) throws Exception { //获得证书 X509Certificate x509Certificate=(X509Certificate)getCertificate(keyStorePath,alias,password); //构建签名,由证书指定签名算法 Signature signature=Signature.getInstance(x509Certificate.getSigAlgName()); //获取私钥 PrivateKey privateKey=getPrivateKeyByKeyStore(keyStorePath, alias, password); //初始化签名,由私钥构建 signature.initSign(privateKey); signature.update(data); return signature.sign(); } /** * 签名验证 * @param data 数据 * @param sign 签名 * @param certificatePath 证书路径 * @return boolean 验证通过为true * @throws Exception */ public static boolean verify(byte[] data,byte[] sign,String certificatePath) throws Exception { //获得证书 X509Certificate x509Certificate=(X509Certificate)getCertificate(certificatePath); //构建签名,由证书指定签名算法 Signature signature=Signature.getInstance(x509Certificate.getSigAlgName()); //由证书初始化签名,实际上是使用了证书中的公钥 signature.initVerify(x509Certificate); signature.update(data); return signature.verify(sign); } } package com.algorithm; import java.io.InputStream; import org.apache.commons.codec.binary.Hex; /** * 数字证书测试用例 * @author Administrator * */ public class CertificateCoderTest { //生成证书时的密码 private static String password="123456"; //别名 private static String alias="www.dominic.com"; //证书路径 private static String certificatePath="D:\\Program Files\\OpenSSL-Win32\\ca\\certs\\dominic.cer"; //密钥库路径 private static String keyStorePath="D:\\Program Files\\OpenSSL-Win32\\ca\\certs\\domini.keystore"; /** * 公钥加密私钥解密 */ public static void test1() throws Exception { String inputStr="数字证书"; byte[] data=inputStr.getBytes(); //公钥加密 byte[] encrypt=CertificateCoder.encryptByPublicKey(data, certificatePath); //私钥解密 byte[] decrypt=CertificateCoder.decryptByPrivateKey(encrypt, keyStorePath, alias, password); System.out.println(new String(decrypt).equals(inputStr)); } /** * 私加密公钥解密 */ public static void test2() throws Exception { String inputStr="数字证书"; byte[] data=inputStr.getBytes(); //私钥加密 byte[] encrypt=CertificateCoder.encryptByPrivateKey(data, keyStorePath, alias, password); //公钥解密 byte[] decrypt=CertificateCoder.decryptByPublicKey(encrypt, certificatePath); System.out.println(new String(decrypt).equals(inputStr)); } /** * 签名验证 */ public static void test3() throws Exception { String inputStr="数字签名"; byte[] data=inputStr.getBytes(); //私钥签名 byte[] sign=CertificateCoder.sign(data, keyStorePath, alias, password); System.out.println("签名:"+Hex.encodeHexString(sign)); //公钥验证 System.out.println(CertificateCoder.verify(data, sign, certificatePath)); } public static void main(String[] args) throws Exception { CertificateCoderTest.test1(); CertificateCoderTest.test2(); CertificateCoderTest.test3(); } } package com.algorithm; import java.security.Key; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.digest.DigestUtils; /** * AES对称加密算法,组件类 * @author Administrator * */ public abstract class AESCoder { //密钥算法 public static final String ALGORITHM="AES"; //密钥长度(java默认只能处理128位以内的长度,如果需要处理大于128位可以使用JCE解除密钥长度限制) public static final int KEY_SIZE=128; /** * 转换密钥 * @param key 二进制密钥 * @return Key 密钥 * @throws Exception */ private static Key toKey(byte[] key) throws Exception { //实例化AES密钥材料 SecretKey secretKey=new SecretKeySpec(key,ALGORITHM); return secretKey; } /** * 解密 * @param data 待解密数据 * @param key 密钥 * @return byte[] 解密数据 * @throws Exception */ public static byte[] decrypt(byte[] data,byte[] key) throws Exception { //还原密钥 Key k=toKey(key); //实例化 Cipher cipher=Cipher.getInstance(ALGORITHM); //初始化,设置为解密模式 cipher.init(Cipher.DECRYPT_MODE, k); //执行操作 return cipher.doFinal(data); } /** * 解密 * @param data 待解密数据 * @param key 密钥 * @return byte[] 解密数据 * @throws Exception */ public static byte[] decrypt(byte[] data,String key) throws Exception { return decrypt(data,getKey(key)); } /** * 加密 * @param data 待加密数据 * @param key 密钥 * @return byte[] 加密数据 * @throws Exception */ public static byte[] encrypt(byte[] data,byte[] key) throws Exception { //还原密钥 Key k=toKey(key); //实例化 Cipher cipher=Cipher.getInstance(ALGORITHM); //初始化,设置为加密模式 cipher.init(Cipher.ENCRYPT_MODE, k); //执行操作 return cipher.doFinal(data); } /** * 加密 * @param data 待加密数据 * @param key 密钥 * @return byte[] 加密数据 * @throws Exception */ public static byte[] encrypt(byte[] data,String key) throws Exception { return encrypt(data,getKey(key)); } /** * 生成密钥 * @return byte[] 二进制密钥 * @throws Exception */ public static byte[] initKey() throws Exception { //实例化 KeyGenerator kg=KeyGenerator.getInstance(ALGORITHM); //初始化密钥长度 kg.init(KEY_SIZE); //生成秘密密钥 SecretKey secretKey=kg.generateKey(); //获得密钥的二进制编码形式 return secretKey.getEncoded(); } /** * 初始化密钥 * @return String Base64编码密钥 * @throws Exception */ public static String initKeyString() throws Exception { return Base64.encodeBase64String(initKey()); } /** * 获取密钥 * @param key * @return byte[] 密钥 * @throws Exception */ public static byte[] getKey(String key) throws Exception { return Base64.decodeBase64(key); } /** * 摘要处理 * @param data 待摘要数据 * @return String 摘要字符串 */ public static String shaHex(byte[] data) { return DigestUtils.md5Hex(data); } /** * 验证 * @param data 待摘要数据 * @param messageDigest 摘要字符串 * @return 验证结果 */ public static boolean validate(byte[] data,String messageDigest) { return messageDigest.equals(shaHex(data)); } } package com.algorithm; /** * 对称加密算法测试用例 * @author Administrator * */ public class AESCoderTest { public static void main(String args[]) { try { //初始化密钥 String secretKey=AESCoder.initKeyString(); System.out.println("密钥为:"+secretKey); String s="我们的大中国"; //加密数据 byte[] encryptData=AESCoder.encrypt(s.getBytes(), secretKey); //解密数据 byte[] data=AESCoder.decrypt(encryptData, secretKey); //比较 System.out.println(new String(data).equals(s)); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }