Java常用加解密算法
BASE64严格地说,应该说是属于编码格式,而非加密算法。
BASE64严格地说,应该说是属于编码格式,而非加密算法。
加解密:
/** * 加密 */public static String encryptBASE64(byte[] data) { BASE64Encoder encoder = new BASE64Encoder(); return encoder.encode(data);}
/** * 解密 */public static byte[] decryptBASE64(String cipher) { BASE64Decoder decoder = new BASE64Decoder(); byte[] bytes = null; try { bytes = decoder.decodeBuffer(cipher); } catch (IOException e) { e.printStackTrace(); } return bytes;}MD5(Message Digest algorithm 5,信息摘要算法),常用于文件校验。 SHA(Secure Hash Algorithm,安全散列算法),同样属于非可逆的算法,作用与MD5相类似。 MD5输出是128位的,SHA输出是160位的。SHA相较于MD5而言更加安全,当然加密花费时间也更长一点。
先设置常量
private final static String KEY_SHA = "SHA";private final static String KEY_MD5 = "MD5";加密
/** * MD5加密 */public static String encryptMD5(byte[] data) { String cipher = null; try { MessageDigest md5 = MessageDigest.getInstance(KEY_MD5); md5.update(data); cipher = encryptBASE64(md5.digest()); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return cipher;}
/** * SHA加密 */public static String encryptSHA(byte[] data) { String cipher = null; try { MessageDigest sha = MessageDigest.getInstance(KEY_SHA); sha.update(data); cipher = encryptBASE64(sha.digest()); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return cipher;}RSA算法是一种非对称密码算法。详情见RSA算法 )
设置需要用到常量,RSA_INIT_LENGTH
为密钥的初始化长度,密钥的长度越长,安全性就越好,但是加密解密所用的时间就会越多。一次能加密的密文长度为:密钥的长度/8-11。所以1024bit长度的密钥一次可以加密的密文为1024/8-11=117bit。所以非对称加密一般都用于加密对称加密算法的密钥,而不是直接加密内容。对于小文件可以使用RSA加密,但加密过程仍可能会使用分段加密。
private final static String KEY_RSA = "RSA";private final static int RSA_INIT_LENGTH = 1024;/** * 初始化 */public static String[] initRSAKey() { String[] keys = null; try { KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_RSA); keyPairGenerator.initialize(RSA_INIT_LENGTH); KeyPair keyPair = keyPairGenerator.generateKeyPair(); // 公钥 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // 私钥 RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); keys = new String[]{encryptBASE64(publicKey.getEncoded()), encryptBASE64(privateKey.getEncoded())}; } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return keys;}RSA有两个密钥,所以加解密方式也有两种,一种是“私钥加密-公钥解密”,另一种就是“公钥加密-私钥解密”,加解密的实现如下:
/** * 私钥加密 */public static byte[] encryptByPrivateKey(byte[] data, String key) { try { byte[] keyBytes = decryptBASE64(key); // 获得私钥 PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_RSA); Key privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); // 对数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, privateKey); return cipher.doFinal(data); } catch (Exception e) { e.printStackTrace(); } return null;}
/** * 公钥解密 */public static byte[] decryptByPublicKey(byte[] data, String key) { try { // 对私钥解密 byte[] keyBytes = decryptBASE64(key); X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_RSA); Key publicKey = keyFactory.generatePublic(x509EncodedKeySpec); // 对数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, publicKey);
return cipher.doFinal(data); } catch (Exception e) { e.printStackTrace(); } return null;}
/** * 公钥加密 */public static byte[] encryptByPublicKey(byte[] data, String key) { try { // 对公钥解密 byte[] keyBytes = decryptBASE64(key); // 取公钥 X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_RSA); Key publicKey = keyFactory.generatePublic(x509EncodedKeySpec); // 对数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(data); } catch (Exception e) { e.printStackTrace(); } return null;}
/** * 私钥解密 */public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception { try { // 对私钥解密 byte[] keyBytes = decryptBASE64(key); PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_RSA); Key privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); // 对数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(data); } catch (Exception e) { e.printStackTrace(); } return null;}使用RSA进行签名验证。数字签名技术是将摘要信息用发送者的私钥加密,与原文一起传送给接收者。接收者只有用发送者的公钥才能解密被加密的摘要信息,然后用对收到的原文产生一个摘要信息,与解密的摘要信息对比。如果相同,则说明收到的信息是完整的,在传输过程中没有被修改,否则说明信息被修改过,因此数字签名能够验证信息的完整性。
该方法可行有两个的条件:
1、通过公钥推算出私钥的做法不可能实现2、即使传输数据的过程被拦截,因为拦截者没有私钥,改动数据就会导致签名的不一致。(这里需要注意,拦截者还是可以使用公钥对数据进行解密,看到传输的数据的)定义常量
private final static String RSA_MD5 = "MD5withRSA";签名和签名验证
/** * 私钥签名 */public static String signByPrivateKey(byte[] data, String privateKey) { try { // 解密私钥 byte[] keyBytes = decryptBASE64(privateKey); // 构造PKCS8EncodedKeySpec对象 PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes); // 指定加密算法 KeyFactory keyFactory = KeyFactory.getInstance(KEY_RSA); // 取私钥匙对象 PrivateKey privateKey2 = keyFactory.generatePrivate(pkcs8EncodedKeySpec); // 用私钥对信息生成数字签名 Signature signature = Signature.getInstance(RSA_MD5); signature.initSign(privateKey2); signature.update(data); return encryptBASE64(signature.sign()); } catch (Exception e) { e.printStackTrace(); } return null;}
/** * 公钥验证 */public static boolean verifyByPublicKey(byte[] data, String publicKey, String sign) { try { // 解密公钥 byte[] keyBytes = decryptBASE64(publicKey); // 构造X509EncodedKeySpec对象 X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes); // 指定加密算法 KeyFactory keyFactory = KeyFactory.getInstance(KEY_RSA); // 取公钥匙对象 PublicKey publicKey2 = keyFactory.generatePublic(x509EncodedKeySpec); Signature signature = Signature.getInstance(RSA_MD5); signature.initVerify(publicKey2); signature.update(data); // 验证签名是否正常 return signature.verify(decryptBASE64(sign)); } catch (Exception e) { e.printStackTrace(); } return false;}DES(全称为DataEncryption Standard,即数据加密标准),是一种对称加密算法!
定义常量
private final static String KEY_DES = "DES";加解密,其中key是8位的密码
/** * 加密 */public static byte[] encryptDES(byte[] data, String key) { try { SecureRandom random = new SecureRandom(); DESKeySpec desKey = new DESKeySpec(key.getBytes()); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(KEY_DES); SecretKey secureKey = keyFactory.generateSecret(desKey); Cipher cipher = Cipher.getInstance(KEY_DES); cipher.init(Cipher.ENCRYPT_MODE, secureKey, random); return cipher.doFinal(data); } catch (Exception e) { e.printStackTrace(); } return null;}
/** * 解密 */public static byte[] decryptDES(byte[] data, String key) { try { SecureRandom random = new SecureRandom(); DESKeySpec desKey = new DESKeySpec(key.getBytes()); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(KEY_DES); SecretKey secureKey = keyFactory.generateSecret(desKey); Cipher cipher = Cipher.getInstance(KEY_DES); cipher.init(Cipher.DECRYPT_MODE, secureKey, random); return cipher.doFinal(data); } catch (Exception e) { e.printStackTrace(); } return null;}