加密算法有很多种,一般可分为对称加密、非对称加密和单向加密三类算法。
对称加密:发送方将明文和加密密钥一起经过加密算法处理变成密文,接收方收到密文后使用加密密钥和相同算法的逆算法进行解密,得到明文。对称加密通信双方使用的密钥相同,要求解密方必须事先知道加密密钥。其特点是算法公开、计算量小、加密速度快,加密效率高。不足之处是通信双方都使用相同的密钥,安全得不到保证。对称加密代表有AES、DES等。
非对称加密:需要两个密钥,公开密钥和私有密钥,公开密钥对外公开,私有密钥不公开。如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,只有用对应的公开密钥才能解密。非对称加密算法的保密性比较好,它消除了最终用户交换密钥的需要,但加密和解密花费时间长,速度慢,它不适合对文件加密而只适用于对少量数据进行加密。非对称加密代表有RSA、DSA等。
单向加密:该算法在加密过程中不需要使用密钥,加密算法直接将明文转化为密文,且算法不可逆,所以密文无法解密,只有重新输入明文,并经过同样加密算法处理,得到相同的密文,和先前的密文进行比较,来达到解密的目的。单向加密代表有MD5。
下面是几种加密算法的Java代码实现
需要依赖jar包commons-codec.jar,到http://mvnrepository.com/下载
Java实现AES
package com; import java.security.InvalidKeyException; import java.security.Key; import java.security.NoSuchAlgorithmException; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.KeyGenerator; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Base64; /** * AES对称加密 */ public class AESCoder { /** * 生成密钥 * * @return String 密钥字符串 * @throws NoSuchAlgorithmException */ public static String generateKey() throws NoSuchAlgorithmException { // 实例化 KeyGenerator kg = KeyGenerator.getInstance("AES"); // 生成密钥 SecretKey sk = kg.generateKey(); // 获得密钥字符串 String key = Base64.encodeBase64String(sk.getEncoded()); return key; } /** * 加密 * * @param data * 待加密数据 * @param key * 密钥 * @return String 加密数据 * @throws NoSuchPaddingException * @throws NoSuchAlgorithmException * @throws InvalidKeyException * @throws BadPaddingException * @throws IllegalBlockSizeException */ public static String encrypt(String data, String key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { // 还原密钥 Key k = new SecretKeySpec(Base64.decodeBase64(key), "AES"); // 实例化 Cipher c = Cipher.getInstance("AES"); // 初始化,设置为加密模式 c.init(Cipher.ENCRYPT_MODE, k); // 执行操作 byte[] encbyte = c.doFinal(data.getBytes()); // 加密数据转为字符串输出 String enc = Base64.encodeBase64String(encbyte); return enc; } /** * 解密 * * @param data * 待解密数据 * @param key * 密钥 * @return String 解密数据 * @throws NoSuchPaddingException * @throws NoSuchAlgorithmException * @throws InvalidKeyException * @throws BadPaddingException * @throws IllegalBlockSizeException */ public static String decrypt(String data, String key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { // 还原密钥 Key k = new SecretKeySpec(Base64.decodeBase64(key), "AES"); // 实例化 Cipher c = Cipher.getInstance("AES"); // 初始化,设置为解密模式 c.init(Cipher.DECRYPT_MODE, k); // 执行操作 byte[] decbyte = c.doFinal(Base64.decodeBase64(data)); // 解密数据转为字符串输出 String dec = new String(decbyte); return dec; } public static void main(String[] args) { try { String msg = "天王盖地虎"; String key = AESCoder.generateKey(); System.out.println("密钥:" + key); System.out.println("明文:" + msg); String enc = AESCoder.encrypt(msg, key); System.out.println("密文:" + enc); String dec = AESCoder.decrypt(enc, key); System.out.println("解密后:" + dec); } catch (Exception e) { e.printStackTrace(); } } }
Java实现DES
package com; import java.security.InvalidKeyException; import java.security.Key; import java.security.NoSuchAlgorithmException; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.KeyGenerator; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Base64; /** * DES对称加密 */ public class DESCoder { /** * 生成密钥 * * @return String 密钥字符串 * @throws NoSuchAlgorithmException */ public static String generateKey() throws NoSuchAlgorithmException { // KeyGenerator提供对称密钥生成器的功能,支持各种算法 KeyGenerator kg = KeyGenerator.getInstance("DES"); // SecretKey负责保存对称密钥 SecretKey sk = kg.generateKey(); // 产生密钥字符串 String key = Base64.encodeBase64String(sk.getEncoded()); return key; } /** * 数据加密 * * @param data * 需要加密的数据 * @param key * 密钥 * @return * @throws NoSuchPaddingException * @throws NoSuchAlgorithmException * @throws InvalidKeyException * @throws BadPaddingException * @throws IllegalBlockSizeException */ public static String encrypt(String data, String key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { // 还原密钥 Key k = new SecretKeySpec(Base64.decodeBase64(key), "DES"); // Cipher负责完成加密或解密工作 Cipher c = Cipher.getInstance("DES"); // 根据密钥,对Cipher对象进行初始化,ENCRYPT_MODE表示加密模式 c.init(Cipher.ENCRYPT_MODE, k); // 加密操作,结果保存进byte数组 byte[] encbyte = c.doFinal(data.getBytes()); // 加密数据转为字符串输出 String enc = Base64.encodeBase64String(encbyte); return enc; } /** * 数据解密 * * @param data * 需要解密的数据 * @param key * 密钥 * @return * @throws NoSuchPaddingException * @throws NoSuchAlgorithmException * @throws InvalidKeyException * @throws BadPaddingException * @throws IllegalBlockSizeException */ public static String decrypt(String data, String key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { // 还原密钥 Key k = new SecretKeySpec(Base64.decodeBase64(key), "DES"); // Cipher负责完成加密或解密工作 Cipher c = Cipher.getInstance("DES"); // 根据密钥,对Cipher对象进行初始化,DECRYPT_MODE表示解密模式 c.init(Cipher.DECRYPT_MODE, k); // 解密操作,结果保存进byte数组 byte[] decbyte = c.doFinal(Base64.decodeBase64(data)); // 解密数据转为字符串输出 String dec = new String(decbyte); return dec; } public static void main(String[] args) { try{ String msg = "宝塔镇河妖"; String key = DESCoder.generateKey(); System.out.println("密钥:" + key); System.out.println("明文:" + msg); String enc = DESCoder.encrypt(msg, key); System.out.println("密文:" + enc); String dec = DESCoder.decrypt(enc, key); System.out.println("解密后:" + dec); } catch (Exception e){ e.printStackTrace(); } } }
Java实现RSA
package com; import java.io.ByteArrayOutputStream; 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.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.SignatureException; 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 java.util.HashMap; import java.util.Map; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import org.apache.commons.codec.binary.Base64; /** * RSA非对称加密 */ public class RSACoder { // 数字签名 签名/验证算法 private static final String SIGNATURE_ALGORRITHM = "SHA1withRSA"; // 公钥变量名 private static final String PUBLIC_KEY = "RSAPublicKey"; // 私钥变量名 private static final String PRIVATE_KEY = "RSAPrivateKey"; // RSA密钥长度,默认为1024,密钥长度必须是64的倍数,范围在512~65526位之间 private static final int KEY_SIZE = 1024; //RSA最大加密明文大小 private static final int MAX_ENCRYPT_BLOCK = 117; //RSA最大解密密文大小 private static final int MAX_DECRYPT_BLOCK = 128; /** * 生成密钥 * * @return 密钥Map * @throws NoSuchAlgorithmException */ public static Map<String, String> generateKey() throws NoSuchAlgorithmException { // 实例化实钥对生成器 KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA"); // 初始化密钥对生成器 keyPairGen.initialize(KEY_SIZE); // 生成密钥对 KeyPair keyPair = keyPairGen.generateKeyPair(); // 公钥 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // 私钥 RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); // 封装密钥 Map<String, String> keyMap = new HashMap<String, String>(2); keyMap.put(PUBLIC_KEY, Base64.encodeBase64String(publicKey.getEncoded())); keyMap.put(PRIVATE_KEY, Base64.encodeBase64String(privateKey.getEncoded())); return keyMap; } /** * 私钥加密 * * @param data * 待加密数据 * @param key * 私钥 * @return String 加密数据 * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException * @throws NoSuchPaddingException * @throws InvalidKeyException * @throws BadPaddingException * @throws IllegalBlockSizeException * @throws IOException */ public static String encryptByPrivateKey(String data, String key) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, IOException { byte[] keybyte = Base64.decodeBase64(key); // 取得私钥 PKCS8EncodedKeySpec封装私钥的类 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keybyte); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); // 生成私钥 PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec); // 对数据加密 Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, privateKey); byte[] databyte = data.getBytes(); int inputLen = databyte.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; while (inputLen - offSet > 0){ if (inputLen - offSet > MAX_ENCRYPT_BLOCK){ cache = cipher.doFinal(databyte, offSet, MAX_ENCRYPT_BLOCK); }else{ cache = cipher.doFinal(databyte, offSet, inputLen - offSet); } out.write(cache); i++; offSet = i * MAX_ENCRYPT_BLOCK; } byte[] encbyte = out.toByteArray(); String enc = Base64.encodeBase64String(encbyte); out.close(); return enc; } /** * 公钥加密 * * @param data * 待加密数据 * @param key * 公钥 * @return String 加密数据 * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException * @throws NoSuchPaddingException * @throws InvalidKeyException * @throws BadPaddingException * @throws IllegalBlockSizeException * @throws IOException */ public static String encryptByPublicKey(String data, String key) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, IOException { byte[] keybyte = Base64.decodeBase64(key); // 取得公钥 X509EncodedKeySpec封装公钥的类 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keybyte); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); // 生成公钥 PublicKey publicKey = keyFactory.generatePublic(x509KeySpec); // 对数据加密 Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] databyte = data.getBytes(); int inputLen = databyte.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; while (inputLen - offSet > 0){ if (inputLen - offSet > MAX_ENCRYPT_BLOCK){ cache = cipher.doFinal(databyte, offSet, MAX_ENCRYPT_BLOCK); }else{ cache = cipher.doFinal(databyte, offSet, inputLen - offSet); } out.write(cache); i++; offSet = i * MAX_ENCRYPT_BLOCK; } byte[] encbyte = out.toByteArray(); String enc = Base64.encodeBase64String(encbyte); out.close(); return enc; } /** * 私钥解密 * * @param data * 待解密数据 * @param key * 私钥 * @return String 解密数据 * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException * @throws NoSuchPaddingException * @throws InvalidKeyException * @throws BadPaddingException * @throws IllegalBlockSizeException * @throws IOException */ public static String decryptByPrivateKey(String data, String key) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, IOException { byte[] keybyte = Base64.decodeBase64(key); // 取得私钥 PKCS8EncodedKeySpec封装私钥的类 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keybyte); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); // 生成私钥 PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec); // 对数据解密 Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] databyte = Base64.decodeBase64(data); int inputLen = databyte.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; while (inputLen - offSet > 0){ if (inputLen - offSet > MAX_DECRYPT_BLOCK){ cache = cipher.doFinal(databyte, offSet, MAX_DECRYPT_BLOCK); }else{ cache = cipher.doFinal(databyte, offSet, inputLen - offSet); } out.write(cache); i++; offSet = i * MAX_DECRYPT_BLOCK; } byte[] decbyte = out.toByteArray(); String dec = new String(decbyte); out.close(); return dec; } /** * 公钥解密 * * @param data * 待解密数据 * @param key * 公钥 * @return String 解密数据 * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException * @throws NoSuchPaddingException * @throws InvalidKeyException * @throws BadPaddingException * @throws IllegalBlockSizeException * @throws IOException */ public static String decryptByPublicKey(String data, String key) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, IOException { byte[] keybyte = Base64.decodeBase64(key); // 取得公钥 X509EncodedKeySpec封装公钥的类 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keybyte); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); // 生成公钥 PublicKey publicKey = keyFactory.generatePublic(x509KeySpec); // 对数据解密 Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, publicKey); byte[] databyte = Base64.decodeBase64(data); int inputLen = databyte.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; while (inputLen - offSet > 0){ if (inputLen - offSet > MAX_DECRYPT_BLOCK){ cache = cipher.doFinal(databyte, offSet, MAX_DECRYPT_BLOCK); }else{ cache = cipher.doFinal(databyte, offSet, inputLen - offSet); } out.write(cache); i++; offSet = i * MAX_DECRYPT_BLOCK; } byte[] decbyte = out.toByteArray(); String dec = new String(decbyte); out.close(); return dec; } /** * 私钥签名 * * @param data * 待签名的加密数据 * @param privateKey * 私钥 * @return String 数字签名 * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException * @throws InvalidKeyException * @throws SignatureException */ public static String sign(String data, String privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException { byte[] privateKeyByte = Base64.decodeBase64(privateKey); // 转接私钥材料 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKeyByte); // 实例化密钥工厂 KeyFactory keyFactory = KeyFactory.getInstance("RSA"); // 取私钥对象 PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec); // 实例化Signature Signature signature = Signature.getInstance(SIGNATURE_ALGORRITHM); // 初始化Signature signature.initSign(priKey); // 更新 signature.update(Base64.decodeBase64(data)); // 签名 byte[] signbyte = signature.sign(); String signstr = Base64.encodeBase64String(signbyte); return signstr; } /** * 公钥校验 * * @param data * 待校验数据 * @param publicKey * 公钥 * @param sign * 数字签名 * @return * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException * @throws InvalidKeyException * @throws SignatureException */ public static boolean verify(String data, String publicKey, String sign) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException { byte[] publicKeyByte = Base64.decodeBase64(publicKey); // 转接公钥材料 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(publicKeyByte); // 实例化密钥工厂 KeyFactory keyFactory = KeyFactory.getInstance("RSA"); // 生成公钥 PublicKey pubKey = keyFactory.generatePublic(x509KeySpec); // 实例化Signature Signature signature = Signature.getInstance(SIGNATURE_ALGORRITHM); // 初始化Signature signature.initVerify(pubKey); // 更新 signature.update(Base64.decodeBase64(data)); // 验证 boolean isVerify = signature.verify(Base64.decodeBase64(sign)); return isVerify; } public static void main(String[] args) throws Exception{ Map<String, String> keyMap = RSACoder.generateKey(); String privateKey = keyMap.get(RSACoder.PRIVATE_KEY); String publicKey = keyMap.get(RSACoder.PUBLIC_KEY); System.out.println("私钥:"+privateKey); System.out.println("公钥:"+publicKey); String str1 = "地振高冈,一派西山千古绣"; System.out.println("私钥加密明文:"+str1); String priEnc = RSACoder.encryptByPrivateKey(str1, privateKey); System.out.println("私钥加密密文:"+priEnc); String sign = RSACoder.sign(priEnc, privateKey); System.out.println("私钥签名:"+sign); boolean verify = RSACoder.verify(priEnc, publicKey, sign); System.out.println("公钥验证:"+verify); String pubDec = RSACoder.decryptByPublicKey(priEnc, publicKey); System.out.println("公钥解密后:"+pubDec); System.out.println(); String str2 = "门朝大海,三河合水万年流"; System.out.println("公钥加密明文:"+str2); String pubEnc = RSACoder.encryptByPublicKey(str2, publicKey); System.out.println("公钥加密密文:"+pubEnc); String priDec = RSACoder.decryptByPrivateKey(pubEnc, privateKey); System.out.println("私钥解密后:"+priDec); } }
注意:使用RSA加密或解密时,明文和密文的长度有大小限制,当明文或密文的长度超过限制长度时,就会抛出异常javax.crypto.IllegalBlockSizeException: Data must not be longer than 117 bytes,此时就需要使用循环语句对过长的明文或密文进行分段加密或解密,然后把分段加密或解密后的数据重新组装,得到最终需要的数据。
还需要说明的是明文和密文的长度限制会根据密钥的长度(64的倍数,范围在512~65526之间)不同而有所变化:当密钥长度为512时,明文和密文的长度限制分别为53字节和53字节;当密钥长度为1024时,明文和密文的长度限制分别为117字节和128字节。
Java实现MD5
package com; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Hex; /** * MD5单向加密 */ public class MD5Coder { /** * MD5加密 * @param str * @return * @throws NoSuchAlgorithmException */ public static String encrypt(String str) throws NoSuchAlgorithmException{ MessageDigest md5 = MessageDigest.getInstance("MD5"); md5.update(str.getBytes()); byte[] md5byte = md5.digest(); String enc = Base64.encodeBase64String(md5byte); //String enc = Hex.encodeHexString(md5byte); return enc; } /** * @param args * @throws NoSuchAlgorithmException */ public static void main(String[] args) { try{ String str = "天王盖地虎,宝塔镇河妖"; String enc = MD5Coder.encrypt(str); System.out.println(enc); }catch(NoSuchAlgorithmException e){ e.printStackTrace(); } } }
相关推荐
Java加密技术
### Java加密技术详解:以MD5为例 在Java中,加密技术是确保数据安全和完整性的关键工具之一。本文将深入探讨Java中的加密技术,特别是MD5加密算法,通过实例和代码片段,帮助读者理解其工作原理及如何在实际项目中...
总之,Java加密技术提供了丰富的工具和算法,可以帮助开发者构建安全的应用程序。然而,随着技术的发展,加密算法的安全性也需要不断更新,以抵御新的攻击手段。在设计系统时,应考虑最新的安全标准和最佳实践,确保...
总结来说,Java加密技术第四部分主要介绍了ECC加密技术的概念、其在Java中的有限支持,以及如何通过Java代码实现ECC的加密和解密操作。尽管Java的标准实现并不直接支持ECC的加密/解密,但可以通过扩展和利用非公开...
Java加密技术是保护数据安全的重要工具,广泛应用于网络通信、数据存储、数字签名等领域。本资源包涵盖了Java中常见的加密算法和技术,包括基础的哈希算法、对称加密、非对称加密以及证书签名和SSL/TLS协议。下面将...
Java加密技术是软件开发中一个重要的安全领域,主要用于保护数据的隐私性和完整性。在这个网页版的资源中,可能涵盖了各种加密算法的Java实现,以及它们之间的比较。让我们深入探讨一下这些知识点。 首先,我们来看...
Java加密技术是信息安全领域的重要组成部分,它用于保护数据的隐私性和完整性。在这个“Java加密技术全集”中,我们将会探讨MD5、SHA和BASE64等常见的加密算法及其在Java中的实现。 MD5(Message-Digest Algorithm ...
### Java加密技术详解 #### 一、BASE64与单向加密算法MD5&SHA&MAC ##### BASE64 BASE64是一种编码格式,并非真正的加密算法。它主要用于将二进制数据转换成文本格式的数据,以便在网络上传输。由于某些传输协议只...
Java加密技术是软件开发中一个至关重要的领域,特别是在保护数据安全、验证信息完整性和实现安全通信方面。本书“Java加密技术(技巧与实例)”深入浅出地探讨了这一主题,为开发者提供了丰富的实践指导。以下是一些...
Java加密技术是软件开发中的重要组成部分,特别是在保护数据安全、用户隐私以及确保网络通信的完整性方面。本资源主要关注两种常见的加密算法:MD5(Message-Digest Algorithm 5)和BASE64编码,它们在Java中有着...
java加密技术研究
Java加密技术(三),相当有用的加密技术(三),值得学习参考!希望对你有点帮助!