一、简介 RSA加密是一种非对称加密。可以在不直接传递密钥的情况下,完成解密。这能够确保信息的安全性,避免了直接传递密钥所造成的被破解的风险。是由一对密钥来进行加解密的过程,分别称为公钥和私钥。两者之间有数学相关,该加密算法的原理就是对一极大整数做因数分解的困难性来保证安全性。通常个人保存私钥,公钥是公开的(可能同时多人持有)。
二、加签、加密说明 加密和加签(签名)都是为了安全性考虑,但略有不同。简单的说,加密是为了防止信息被泄露,而加签(签名)是为了防止信息被篡改。
三、加密/解密 1、A生成一对密钥(公钥和私钥),私钥不公开,A自己保留。公钥为公开的,任何人可以获取。 2、A传递自己的公钥给B,B用A的公钥对消息进行加密。 3、A接收到B加密的消息,利用A自己的私钥对消息进行解密。
四、加签/验签
五、代码例子
/** * 加签(签名) * * @param data 原始数据 * @param privateKey 私钥 * @return 加签后的串 */ public static String sign(String data, String privateKey) { try { Signature signature = Signature.getInstance("MD5withRSA"); signature.initSign(getPrivateKey(privateKey)); signature.update(data.getBytes()); return new String(Base64.encodeBase64(signature.sign())); } catch (Exception e) { LOGGER.warn("RsaUtils.sign error {}", e); } return null; } /** * 验签 * * @param data 原始数据 * @param publicKey 公钥 * @param sign 签名 * @return true:成功 false:失败 */ public static boolean verify(String data, String publicKey, String sign) { try { Signature signature = Signature.getInstance("MD5withRSA"); signature.initVerify(getPublicKey(publicKey)); signature.update(data.getBytes()); return signature.verify(Base64.decodeBase64(sign.getBytes())); } catch (Exception e) { LOGGER.warn("RsaUtils.verify error {}", e); } return false; } /** * RSA加密 * * @param data 待加密数据 * @param publicKey 公钥 * @return 加密后的串 */ public static String encrypt(String data, String publicKey) throws Exception { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, getPublicKey(publicKey)); int inputLen = data.getBytes().length; ByteArrayOutputStream bao = null; try { bao = new ByteArrayOutputStream(); int offset = 0; byte[] cache; int i = 0; // 对数据分段加密 while (inputLen - offset > 0) { if (inputLen - offset > MAX_ENCRYPT_BLOCK) { cache = cipher.doFinal(data.getBytes(), offset, MAX_ENCRYPT_BLOCK); } else { cache = cipher.doFinal(data.getBytes(), offset, inputLen - offset); } bao.write(cache, 0, cache.length); i++; offset = i * MAX_ENCRYPT_BLOCK; } byte[] encryptedData = bao.toByteArray(); return Base64.encodeBase64String(encryptedData); } catch (Exception e) { throw e; } finally { if (null != bao) { bao.close(); } } } /** * RSA解密 * * @param data 待解密数据 * @param privateKey 私钥 * @return 解密后的串 */ public static String decrypt(String data, String privateKey) throws Exception { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, getPrivateKey(privateKey)); byte[] dataBytes = Base64.decodeBase64(data); int inputLen = dataBytes.length; ByteArrayOutputStream bao = null; try { bao = new ByteArrayOutputStream(); int offset = 0; byte[] cache; int i = 0; // 对数据分段解密 while (inputLen - offset > 0) { if (inputLen - offset > MAX_DECRYPT_BLOCK) { cache = cipher.doFinal(dataBytes, offset, MAX_DECRYPT_BLOCK); } else { cache = cipher.doFinal(dataBytes, offset, inputLen - offset); } bao.write(cache, 0, cache.length); i++; offset = i * MAX_DECRYPT_BLOCK; } byte[] decryptedData = bao.toByteArray(); // 解密后的内容 return new String(decryptedData, Constants.DEFAULT_CHARSET); } catch (Exception e) { throw e; } finally { if (null != bao) { bao.close(); } } } /** * 创建公钥/私钥串 * * @return 数据对象 */ public static KeyDTO createKeyPair() { try { KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA"); generator.initialize(512); KeyPair keyPair = generator.generateKeyPair(); KeyDTO keyDTO = new KeyDTO(); keyDTO.setPrivateKey(new String(Base64.encodeBase64(keyPair.getPrivate().getEncoded()))); keyDTO.setPublicKey(new String(Base64.encodeBase64(keyPair.getPublic().getEncoded()))); return keyDTO; } catch (NoSuchAlgorithmException e) { LOGGER.warn("RsaUtils.createKeyPair error {}", e); } return null; } private static PrivateKey getPrivateKey(String privateKey) throws Exception { KeyFactory keyFactory = KeyFactory.getInstance("RSA"); return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey.getBytes()))); } private static PublicKey getPublicKey(String publicKey) throws Exception { KeyFactory keyFactory = KeyFactory.getInstance("RSA"); return keyFactory.generatePublic(new X509EncodedKeySpec(Base64.decodeBase64(publicKey.getBytes()))); }结论:公钥加密、私钥解密、私钥签名、公钥验签