文章目录
- 一、加解密
- 1,RSA
- 2,DES
- 3,AES
- 二、不可逆加密
- 1,MD5
- 2,SHA256
- 三、签名
- 1,RSA
- 2,DSA
签名是为了验证数据的来源和完整性
加密是为了保护数据的内容,使其对未授权的用户不可读
一、加解密
1,RSA
一种非对称加密算法,有两个不同的密钥,一个是公钥,一个是私钥
名称由来:Ron Rivest、Adi Shamir、Leonard Adleman,由三位在麻省理工学院工作的人的姓氏开头首字母组成
public static void cipherRSA(String orgStr){
try {KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");keyPairGenerator.initialize(2048);KeyPair keyPair = keyPairGenerator.generateKeyPair();PublicKey publicKey = keyPair.getPublic();PrivateKey privateKey = keyPair.getPrivate();Cipher encryCipher = Cipher.getInstance("RSA");encryCipher.init(Cipher.ENCRYPT_MODE,publicKey);byte[] encrypted = encryCipher.doFinal(orgStr.getBytes());String encryRes = Base64.getEncoder().encodeToString(encrypted);System.out.println("RSA加密结果==>" + encryRes);Cipher decryCipher = Cipher.getInstance("RSA");decryCipher.init(Cipher.DECRYPT_MODE,privateKey);byte[] decrypted = decryCipher.doFinal(encrypted);String decryRes = new String(decrypted);System.out.println("RSA解密结果==>" + decryRes);}catch (Exception e){e.printStackTrace();
}
}
执行结果:加密结果每次都不一样
RSA加密结果==>P4m9ZPe1ApCWt21cND83Hj4ArPvrjrzWPrR9ktJCPx8IlRWemdd8q4FzHVAYrzzoL58LIlX7yHkOXXKTD9cueHM800HGdLJbpN4Fl21Y81wS+0kqDwDvP1azlsCamTuD2EPR5NbIhbj7TXfNsaM2SKzap38GaTWo+Keu7Nh/ZAgeONPH9VNweRpPrahcgBMZVWJYP9J15Y7Z8bjjSpO5RvaZnqj99A6m4dJTL1l2uOgIqcctAtI+Afc3DrL16PBPXloj/FKR3G3qInOtgT/l14ZoZ/4ixPnKvg/JWcOmpmlf4xPiCg285TFyXGHx+lAEP4FKM45sY2y/gm9Z83TEfA==
RSA解密结果==>山姆超市
2,DES
全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,对称密码体制,加密和解密使用相同的密钥。
public static void cipherDES(String orgStr) {
try {KeyGenerator keyGenerator = KeyGenerator.getInstance("DES");keyGenerator.init(56);SecretKey secretKey = keyGenerator.generateKey();Cipher encryCipher = Cipher.getInstance("DES");encryCipher.init(Cipher.ENCRYPT_MODE, secretKey);byte[] encrypted = encryCipher.doFinal(orgStr.getBytes());StringBuilder hexString = new StringBuilder();for (byte b : encrypted) {hexString.append(String.format("%02X",b));}String myHash = hexString.toString();System.out.println("DES加密结果==>" + myHash);Cipher decryCipher = Cipher.getInstance("DES");decryCipher.init(Cipher.DECRYPT_MODE, secretKey);byte[] org = decryCipher.doFinal(encrypted);String originalString = new String(org);System.out.println("DES解密结果==>" + originalString);
} catch (Exception e) {e.printStackTrace();
}
}
执行结果:每次加密结果不一样
DES加密结果==>748487D7AA6A088294859D44D672BA40
DES解密结果==>山姆超市
3,AES
高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准,为了替换DES
ECB(Electronic Code Book电子密码本)模式
CBC(Cipher Block Chaining,加密块链)模式
public static void cipherAES(String orgStr) {
try {// key长度得是16位byte[] keyBytes = "xmlxmlxmlxmlxml1".getBytes();byte[] iv = "lxmlxmlxmlxmlxm2".getBytes();IvParameterSpec ivSpec = new IvParameterSpec(iv);SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");Cipher encryCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");encryCipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);byte[] encrypted = encryCipher.doFinal(orgStr.getBytes());String res = Base64.getEncoder().encodeToString(encrypted);System.out.println("AES加密结果==>" + res);Cipher decryCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");decryCipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);byte[] org = decryCipher.doFinal(encrypted);String originalString = new String(org);System.out.println("AES解密结果==>" + originalString);
} catch (Exception e) {e.printStackTrace();
}
}
执行结果:加密结果每次都一样
AES加密结果==>Wmk5xZq6NbDHA02C8uqJ0g==
AES解密结果==>山姆超市
二、不可逆加密
只能加密,不能解密,散列是单向不可逆
黑客可通过彩虹表和字典来破解哈希(散列),应对方法是加盐(在密码的随机位置加入随机字符串)
彩虹表就是通过预先计算并存储大量的哈希值与对应的明文密码之间的关系,从而允许快速地从哈希值恢复出原始密码,这种表的大小通常很大,主流的彩虹表大小超过100GB。
1,MD5
Message-Digest Algorithm 5,中文名为消息摘要算法第五版,一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。
public static void encryptMD5(String orgStr){
try {MessageDigest messageDigest = MessageDigest.getInstance("MD5");messageDigest.update(orgStr.getBytes());byte[] digest = messageDigest.digest();StringBuilder stringBuilder = new StringBuilder();for(byte b:digest){stringBuilder.append(String.format("%02x",b));}String myHash = stringBuilder.toString();System.out.println("MD5加密结果==>" + myHash);
}catch (Exception e){e.printStackTrace();
}
}
输入:
encryptMD5(“山姆超市”);
执行结果:字符串长度为32位
MD5加密结果==>d680cd5e34b94a88ea9be28d028cd648
2,SHA256
是SHA 2系列算法细分出的一种算法,其中SHA是 Secure Hash Algorithm(安全散列算法) 的缩写,256值代表最终的哈希值摘要
目前最受推荐的哈希加密算法,被认为是 MD5 的继承者
public static void encryptSHA256(String orgStr) {
try {MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");messageDigest.update(orgStr.getBytes());byte[] digest = messageDigest.digest();StringBuilder hexString = new StringBuilder();for (byte b : digest) {String hex = Integer.toHexString(0xff & b);if (hex.length() == 1) hexString.append('0');hexString.append(hex);}String myHash = hexString.toString();System.out.println("SHA-256加密结果==>" + myHash);
} catch (Exception e) {e.printStackTrace();
}
}
输入:
encryptSHA256("山姆超市");
执行结果:字符串长度为64位
SHA-256加密结果==>19b0a9ff44f815b1dc88751b02ad4b14eb0192253f78fd5baf711f04a4068a77
三、签名
1,RSA
私钥签名,公钥验证
public static void signRSA(String src){try {// 生成RSA密钥对KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");keyPairGenerator.initialize(2048);KeyPair keyPair = keyPairGenerator.generateKeyPair();PublicKey publicKey = keyPair.getPublic();PrivateKey privateKey = keyPair.getPrivate();// 私钥签名Signature signature = Signature.getInstance("SHA256withRSA");signature.initSign(privateKey);signature.update(src.getBytes());byte[] realSign = signature.sign();// 公钥验签signature.initVerify(publicKey);signature.update(src.getBytes());boolean isValid = signature.verify(realSign);System.out.println("RSA Signature is " + (isValid ? "valid" : "invalid"));}catch (Exception e){e.printStackTrace();}}
执行结果
RSA Signature is valid
2,DSA
DSA(Digital Signature Algorithm)是一种数字签名算法,它被广泛用于确保电子文档的完整性和认证。DSA 是美国政府开发的,并在 1994 年成为 FIPS 186 标准的一部分。
可以用于文件签名和数字证书,拥有很高的安全性和唯一性,但速度较慢
ECDSA 和 EdDSA可以用来代替DSA
public static void signDSA(String src){
try {KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DSA");keyPairGenerator.initialize(512);KeyPair keyPair = keyPairGenerator.generateKeyPair();DSAPublicKey dsaPublicKey = (DSAPublicKey) keyPair.getPublic();DSAPrivateKey dsaPrivateKey = (DSAPrivateKey) keyPair.getPrivate();KeyFactory keyFactory = KeyFactory.getInstance("DSA");// 获取私钥PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(dsaPrivateKey.getEncoded());PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);// 初始化签名Signature dsaSign = Signature.getInstance("SHA1withDSA");dsaSign.initSign(privateKey);dsaSign.update(src.getBytes());// 签名byte[] realSign = dsaSign.sign();// 获取公钥X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(dsaPublicKey.getEncoded());PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);// 验签dsaSign.initVerify(publicKey);dsaSign.update(src.getBytes());boolean isValid = dsaSign.verify(realSign);System.out.println("DSA Signature is " + (isValid ? "valid" : "invalid"));}catch (Exception e){e.printStackTrace();
}
}
signDSA("helloworld");
执行结果;
DSA Signature is valid