对称加密与非对称加密实战( 二 )


对称加密与非对称加密实战

文章插图
 
AES加密密码学中的高级加密标准(Advanced Encryption Standard , AES) , 又称Rijndael加密法 , 是美国联邦政府采用的一种区块加密标准 。
public class AESUtil {private static final String KEY_ALGORITHM = "AES";private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";//默认的加密算法/*** AES 加密操作** @param content 待加密内容* @param key 加密密钥* @return 返回Base64转码后的加密数据*/public static String encrypt(String content, String key) {try {Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);// 创建密码器byte[] byteContent = content.getBytes("utf-8");cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(key));// 初始化为加密模式的密码器byte[] result = cipher.doFinal(byteContent);// 加密return Base64.encodeBase64String(result);//通过Base64转码返回} catch (Exception ex) {Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);}return null;}/*** AES 解密操作** @param content* @param key* @return*/public static String decrypt(String content, String key) {try {//实例化Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);//使用密钥初始化 , 设置为解密模式cipher.init(Cipher.DECRYPT_MODE, getSecretKey(key));//执行操作byte[] result = cipher.doFinal(Base64.decodeBase64(content));return new String(result, "utf-8");} catch (Exception ex) {Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);}return null;}/*** 生成加密秘钥** @return*/private static SecretKeySpec getSecretKey(final String key) {//返回生成指定算法密钥生成器的 KeyGenerator 对象KeyGenerator kg = null;try {kg = KeyGenerator.getInstance(KEY_ALGORITHM);//AES 要求密钥长度为 128kg.init(128, new SecureRandom(key.getBytes()));//生成一个密钥SecretKey secretKey = kg.generateKey();return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM);// 转换为AES专用密钥} catch (NoSuchAlgorithmException ex) {Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);}return null;}}
对称加密与非对称加密实战

文章插图
 
 
非对称加密非对称加密算法需要两个密钥:公开密钥(publickey:简称公钥)和私有密钥(privatekey:简称私钥) 。
公钥与私钥是一对 , 如果用公钥对数据进行加密 , 只有用对应的私钥才能解密 。
因为加密和解密使用的是两个不同的密钥 , 所以这种算法叫作非对称加密算法 。
非对称加密算法实现机密信息交换的基本过程是:甲方生成一对密钥并将公钥公开 , 需要向甲方发送信息的其他角色(乙方)使用该密钥(甲方的公钥)对机密信息进行加密后再发送给甲方;甲方再用自己私钥对加密后的信息进行解密 。甲方想要回复乙方时正好相反 , 使用乙方的公钥对数据进行加密 , 同理 , 乙方使用自己的私钥来进行解密 。
算法强度复杂、安全性依赖于算法与密钥但是由于其算法复杂 , 而使得加密解密速度没有对称加密解密的速度快 。对称密码体制中只有一种密钥 , 并且是非公开的 , 如果要解密就得让对方知道密钥 。所以保证其安全性就是保证密钥的安全 , 而非对称密钥体制有两种密钥 , 其中一个是公开的 , 这样就可以不需要像对称密码那样传输对方的密钥了 。这样安全性就大了很多 。
RSA加密RSA是一种非对称加密算法.RSA有两个密钥 , 一个是公开的 , 称为公开密钥;一个是私密的 , 称为私密密钥 。公开密钥是对大众公开的 , 私密密钥是服务器私有的 , 两者不能互推得出 。用公开密钥对数据进行加密 , 私密密钥可解密;私密密钥对数据加密 , 公开密钥可解密 。速度较对称加密慢 。
public class RSAUtils {/*** 加密算法RSA*/public static final String KEY_ALGORITHM = "RSA";/*** 签名算法*/public static final String SIGNATURE_ALGORITHM = "MD5withRSA";/*** 获取公钥的key*/private static final String PUBLIC_KEY = "RSAPublicKey";/*** 获取私钥的key*/private static final String PRIVATE_KEY = "RSAPrivateKey";/*** RSA最大加密明文大小*/private static final int MAX_ENCRYPT_BLOCK = 117;/*** RSA最大解密密文大小*/private static final int MAX_DECRYPT_BLOCK = 128;/*** <p>* 生成密钥对(公钥和私钥)* </p>** @return* @throws Exception*/public static Map<String, Object> genKeyPair() throws Exception {KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);keyPairGen.initialize(1024);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;}/*** <p>* 用私钥对信息生成数字签名* </p>** @param data 已加密数据* @param privateKey 私钥(BASE64编码)** @return* @throws Exception*/public static String sign(byte[] data, String privateKey) throws Exception {byte[] keyBytes = decode(privateKey);PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);signature.initSign(privateK);signature.update(data);return encode(signature.sign());}/*** <p>* 校验数字签名* </p>** @param data 已加密数据* @param publicKey 公钥(BASE64编码)* @param sign 数字签名** @return* @throws Exception**/public static boolean verify(byte[] data, String publicKey, String sign)throws Exception {byte[] keyBytes = decode(publicKey);X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);PublicKey publicK = keyFactory.generatePublic(keySpec);Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);signature.initVerify(publicK);signature.update(data);return signature.verify(decode(sign));}/*** <P>* 私钥解密* </p>** @param encryptedData 已加密数据* @param privateKey 私钥(BASE64编码)* @return* @throws Exception*/public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey)throws Exception {byte[] keyBytes = decode(privateKey);PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, privateK);int inputLen = encryptedData.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(encryptedData, offSet, MAX_DECRYPT_BLOCK);} else {cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);}out.write(cache, 0, cache.length);i++;offSet = i * MAX_DECRYPT_BLOCK;}byte[] decryptedData = https://www.isolves.com/it/cxkf/sf/2020-05-21/out.toByteArray();out.close();return decryptedData;}/***


推荐阅读