1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > RSA双向加解密(公钥加密-私钥解密;私钥加密-公钥解密)

RSA双向加解密(公钥加密-私钥解密;私钥加密-公钥解密)

时间:2019-07-28 03:52:46

相关推荐

RSA双向加解密(公钥加密-私钥解密;私钥加密-公钥解密)

非对称加密算法中,提供一个公钥一个私钥。一般情况下,采用公钥加密、私钥解密的方式。

假设有这样一个场景:服务A与服务B需要通信,通信内容为了安全需要进行加密传输,并且服务A与服务B不能互相持有对方的钥匙。

我首先想到的是能否利用RSA实现双向的加解密,查阅了资料后做了一个简单的实现,下面贴出实现原理及代码:

public class RsaEncryptUtil{public static final String PUBLIC_KEY="publicKey";public static final String PRIVATE_KEY="privateKey";private static final String KEY_STORE = "JKS";private static final int MAX_ENCRYPT_LENGTH = 117;private static final int MAX_DECRYPT_LENGTH = 128;/*** 随机生成RAS公钥与私钥字符串,直接返回*/public static Map<String, String> getKeys() {KeyPairGenerator keyPairGen;try {keyPairGen = KeyPairGenerator.getInstance("RSA");} catch (NoSuchAlgorithmException e) {e.printStackTrace();throw new RSAException("RSA获取钥匙对失败", e);}// 初始化密钥对生成器,密钥大小为96-1024位keyPairGen.initialize(1024,new SecureRandom());// 生成一个密钥对,保存在keyPair中KeyPair keyPair = keyPairGen.generateKeyPair();Map<String,String> keyMap = new HashMap<>();keyMap.put(PUBLIC_KEY, RSACryptUtil.base64ToStr(keyPair.getPublic().getEncoded()));keyMap.put(PRIVATE_KEY, RSACryptUtil.base64ToStr(keyPair.getPrivate().getEncoded()));return keyMap;}/*** 获得KeyStore** @param keyStorePath* @param password*/private static KeyStore getKeyStore(String keyStorePath, String password) throws Exception {FileInputStream is = new FileInputStream(keyStorePath);KeyStore ks = KeyStore.getInstance(KEY_STORE);ks.load(is, password.toCharArray());is.close();return ks;}/*** 由KeyStore获得私钥** @param keyStorePath KeyStore路径* @param alias 别名* @param storePassKeyStore访问密码* @param keyPass 私钥的钥匙密码*/private static PrivateKey loadPrivateKey(String keyStorePath, String alias, String storePass, String keyPass) throws Exception {KeyStore ks = getKeyStore(keyStorePath, storePass);PrivateKey key = (PrivateKey) ks.getKey(alias, keyPass.toCharArray());return key;}/*** 由Certificate获得公钥** @param keyStorePath KeyStore路径* @param alias 别名* @param storePassKeyStore访问密码*/private static PublicKey loadPublicKey(String keyStorePath, String alias, String storePass) throws Exception {KeyStore ks = getKeyStore(keyStorePath, storePass);PublicKey key = ks.getCertificate(alias).getPublicKey();return key;}/*** 公钥加密** @param publicKey公钥* @param content 明文数据*/public static String encryptByPublic(String publicKey, String content){if (StringUtils.isEmpty(publicKey)) {throw new RSAException("加密公钥为空, 请设置");}if(StringUtils.isEmpty(content)){throw new RSAException("加密明文为空, 请设置");}Cipher cipher;StringBuilder result = new StringBuilder();try {// 使用默认RSAcipher = Cipher.getInstance("RSA");cipher.init(Cipher.ENCRYPT_MODE, RSACryptUtil.loadPublicKey(publicKey));byte[] bytes = content.getBytes();for (int i = 0; i < bytes.length; i += MAX_ENCRYPT_LENGTH) {byte[] subarray = ArrayUtils.subarray(bytes, i, i + MAX_ENCRYPT_LENGTH);if(subarray != null && subarray.length > 0){byte[] doFinal = cipher.doFinal(subarray);result.append(RSACryptUtil.base64ToStr(doFinal));}}return result.toString();} catch (NoSuchAlgorithmException e) {throw new RSAException("无此加密算法",e);} catch (NoSuchPaddingException e) {e.printStackTrace();return null;} catch (InvalidKeyException e) {throw new RSAException("加密公钥非法,请检查",e);} catch (IllegalBlockSizeException e) {throw new RSAException("明文长度非法",e);} catch (BadPaddingException e) {throw new RSAException("明文数据已损坏",e);} catch (Exception e) {throw new RSAException("未知错误",e);}}/*** 私钥解密** @param privateKey 私钥* @param content 密文数据*/public static String decryptByPrivate(String privateKey, String content){if (StringUtils.isEmpty(privateKey)) {throw new RSAException("解密私钥为空, 请设置");}if(StringUtils.isEmpty(content)){throw new RSAException("解密密文为空, 请设置");}if(content.length() < 4){throw new RSAException("解密密文有误:" + content);}Cipher cipher;StringBuilder result = new StringBuilder();try {// 使用默认RSAcipher = Cipher.getInstance("RSA");cipher.init(Cipher.DECRYPT_MODE, RSACryptUtil.loadPrivateKey(privateKey));byte[] bytes = RSACryptUtil.strToBase64(content);for (int i = 0; i < bytes.length; i += MAX_DECRYPT_LENGTH) {byte[] subarray = ArrayUtils.subarray(bytes, i, i + MAX_DECRYPT_LENGTH);if(subarray != null && subarray.length > 0){byte[] doFinal = cipher.doFinal(subarray);result.append(new String(doFinal));}}return result.toString();} catch (NoSuchAlgorithmException e) {throw new RSAException("无此解密算法",e);} catch (NoSuchPaddingException e) {e.printStackTrace();return null;} catch (InvalidKeyException e) {throw new RSAException("解密私钥非法,请检查");} catch (IllegalBlockSizeException e) {throw new RSAException("密文长度非法",e);} catch (BadPaddingException e) {throw new RSAException("密文数据已损坏",e);} catch (Exception e) {e.printStackTrace();throw new RSAException("未知错误",e);}}/*** 私钥加密** @param privateKey 私钥* @param content 明文数据*/public static String encryptByPrivate(String privateKey,String content){if (StringUtils.isEmpty(privateKey)) {throw new RSAException("加密私钥为空, 请设置");}if(StringUtils.isEmpty(content)){throw new RSAException("加密明文为空, 请设置");}Cipher cipher;StringBuilder result = new StringBuilder();try {// 使用默认RSAcipher = Cipher.getInstance("RSA");cipher.init(Cipher.ENCRYPT_MODE, RSACryptUtil.loadPrivateKey(privateKey));byte[] bytes = content.getBytes();for (int i = 0; i < bytes.length; i += MAX_ENCRYPT_LENGTH) {byte[] subarray = ArrayUtils.subarray(bytes, i, i + MAX_ENCRYPT_LENGTH);if(subarray != null && subarray.length > 0){byte[] doFinal = cipher.doFinal(subarray);result.append(RSACryptUtil.base64ToStr(doFinal));}}return result.toString();}catch (NoSuchAlgorithmException e) {throw new RSAException("无此加密算法",e);} catch (NoSuchPaddingException e) {e.printStackTrace();return null;} catch (InvalidKeyException e) {throw new RSAException("加密私钥非法,请检查",e);} catch (IllegalBlockSizeException e) {throw new RSAException("明文长度非法",e);} catch (BadPaddingException e) {throw new RSAException("明文数据已损坏",e);}}/*** 公钥解密** @param publicKey公钥* @param content 密文数据*/public static String decryptByPublic(String publicKey, String content){if (StringUtils.isEmpty(publicKey)) {throw new RSAException("解密公钥为空, 请设置");}if(StringUtils.isEmpty(content)){throw new RSAException("解密密文为空, 请设置");}if(content.length() < 4){throw new RSAException("解密密文有误:" + content);}Cipher cipher;StringBuilder result = new StringBuilder();try {// 使用默认RSAcipher = Cipher.getInstance("RSA");cipher.init(Cipher.DECRYPT_MODE, RSACryptUtil.loadPublicKey(publicKey));byte[] bytes = RSACryptUtil.strToBase64(content);for (int i = 0; i < bytes.length; i += MAX_DECRYPT_LENGTH) {byte[] subarray = ArrayUtils.subarray(bytes, i, i + MAX_DECRYPT_LENGTH);if(subarray != null && subarray.length > 0){byte[] doFinal = cipher.doFinal(subarray);result.append(new String(doFinal));}}return result.toString();}catch (NoSuchAlgorithmException e) {throw new RSAException("无此解密算法",e);} catch (NoSuchPaddingException e) {e.printStackTrace();return null;} catch (InvalidKeyException e) {throw new RSAException("解密公钥非法,请检查",e);} catch (IllegalBlockSizeException e) {throw new RSAException("密文长度非法",e);} catch (BadPaddingException e) {throw new RSAException("密文数据已损坏",e);}}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。