package com.tebon.ams.util;

import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;

import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

/**
* @description: ${description}
* @author: dfz
* @create: 2019-05-16
**/
public class RSA {
private static Logger logger = Logger.getLogger(RSA.class);

private static final String KEY_ALGORITHM = "RSA";
private static final int RSA_KEY_SIZE = 1024;
public final static String UTF8 = "utf-8";
private static Map<Integer, String> keyMap = new HashMap<Integer, String>();

public static String formatString(String source) {
if (source == null) {
return null;
}
return source.replaceAll("\\r", "").replaceAll("\\n", "");
}

//用于封装随机产生的公钥与私钥
public static void main(String[] args) throws Exception {
//生成公钥和私钥
genKeyPair();
//加密字符串
String message = "df723820";
System.out.println("随机生成的公钥为:" + keyMap.get(0));
System.out.println("随机生成的私钥为:" + keyMap.get(1));

//公钥加密、私钥解密
String messageEn = encrypt(message, keyMap.get(0));
System.out.println(message + "公钥加密后的字符串为:" + messageEn);
String messageDe = decrypt(messageEn, keyMap.get(1));
System.out.println("私钥解密字符串为:" + messageDe);

//私钥加密、公钥解密
String enc = encryptByPrivateKey(message, keyMap.get(1));
System.out.println(message + "私钥加密后的字符串为:" + enc);
String de = decryptByPublicKey(enc, keyMap.get(0));
System.out.println("公钥解密后的字符串:" + de);

}

/**
* 随机生成密钥对
*
* @throws NoSuchAlgorithmException
*/
public static void genKeyPair() throws NoSuchAlgorithmException {
//KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
//初始化密钥对生成器,密钥大小为96-1024位
keyPairGen.initialize(RSA_KEY_SIZE, new SecureRandom());
// 生成一个密钥对,保存在keyPair中
KeyPair keyPair = keyPairGen.generateKeyPair();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
// 得到私钥
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
// 得到公钥
String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));
// 得到私钥字符串
String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded())));
// 将公钥和私钥保存到Map
keyMap.put(0, publicKeyString);// 0表示公钥
keyMap.put(1, privateKeyString);// 1表示私钥
}

/**
* RSA公钥加密
*
* @param str 加密字符串
* @param publicKey 公钥
* @return 密文
* @throws Exception 加密过程中的异常信息
*/

public static String encrypt(String str, String publicKey) throws Exception {
publicKey = formatString(publicKey);
//base64编码的公钥
byte[] decoded = Base64.decodeBase64(publicKey);
RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance(KEY_ALGORITHM).generatePublic(new X509EncodedKeySpec(decoded));
//RSA加密
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
String outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes(UTF8)));
return outStr;
}

/**
* RSA私钥解密
*
* @param str 加密字符串
* @param privateKey 私钥
* @return 铭文
* @throws Exception 解密过程中的异常信息
*/
public static String decrypt(String str, String privateKey) throws Exception {
privateKey = formatString(privateKey);
//64位解码加密后的字符串
byte[] inputByte = Base64.decodeBase64(str.getBytes(UTF8));
// base64编码的私钥
byte[] decoded = Base64.decodeBase64(privateKey);
RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance(KEY_ALGORITHM).generatePrivate(new PKCS8EncodedKeySpec(decoded));
// RSA解密
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, priKey);
String outStr = new String(cipher.doFinal(inputByte));
return outStr;
}

/**
* 私钥加密
*
* @param data 加密数据
* @param privateKey 私钥
* @return
*/
public static String encryptByPrivateKey(String data, String privateKey) {
try {
privateKey = formatString(privateKey);
byte[] kb = Base64.decodeBase64(privateKey.getBytes(UTF8));
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(kb);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PrivateKey key = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] b = data.getBytes(UTF8);
byte[] encrypt = cipher.doFinal(b);
return Base64.encodeBase64String(encrypt);
} catch (Exception e) {
logger.error("Failed to encryptByPrivateKey data.", e);
throw new RuntimeException();
}
}

/**
* 公钥解密
*
* @param data 解密数据
* @param publicKey 公钥
* @return
*/
public static String decryptByPublicKey(String data, String publicKey) {
try {
publicKey = formatString(publicKey);
byte[] kb = Base64.decodeBase64(publicKey.getBytes(UTF8));
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(kb);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PublicKey key = keyFactory.generatePublic(x509EncodedKeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
//Cipher cipher = Cipher.getInstance(RSA_PADDING_KEY);
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] b = data.getBytes(UTF8);
byte[] decrypt = cipher.doFinal(Base64.decodeBase64(b));
return new String(decrypt, UTF8);
} catch (Exception e) {
logger.error("Failed to decryptByPublicKey data.", e);
throw new RuntimeException();
}
}
}

RSA公钥加密-私钥解密/私钥加密-公钥解密的更多相关文章

  1. RSA不对称加密,公钥加密私钥解密,私钥加密公钥解密

    RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作. RSA是被研究得最广泛的公钥算法,从提出到现在已近二十年,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一 ...

  2. RSA 加密算法 Java 公钥加密私钥解密 和 私钥加密公钥解密 的特点

    package com.smt.cipher.unsymmetry; import org.apache.commons.codec.binary.Base64; import org.apache. ...

  3. C# 基于大整数类的RSA算法实现(公钥加密私钥解密,私钥加密公钥解密)

    但是C#自带的RSA算法类RSACryptoServiceProvider只支持公钥加密私钥解密,即数字证书的使用. 所以参考了一些网上的资料写了一个RSA的算法实现.算法实现是基于网上提供的一个大整 ...

  4. 基于私钥加密公钥解密的RSA算法C#实现

    RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作. RSA是被研究得最广泛的公钥算法,从提出到现在已近二十年,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一 ...

  5. 求求你们不要再用 RSA 私钥加密公钥解密了,这非常不安全!

    最近经常在网上看到有人说巨硬的 CNG(Cryptography Next Generation 即下一代加密技术) 只提供 RSA 公钥加密私钥解密,没有提供 RSA 私钥加密公钥解密,他们要自己封 ...

  6. 银联手机支付(.Net Csharp),3DES加密解密,RSA加密解密,RSA私钥加密公钥解密,.Net RSA 3DES C#

    前段时间做的银联支付,折腾了好久,拼凑的一些代码,有需要的朋友可以参考,本人.Net新手,不保证准确性! 这个银联手机支付没有SDK提供,技术支持也没有.Net的,真心不好搞! RSA加解密,这里有个 ...

  7. RSA加解密 私钥加密公钥解密 私加公解 && C++ 调用openssl库 的代码实例

    前提:秘钥长度=1024 ============================================== 对一片(117字节)明文加密  私加 ===================== ...

  8. golang 私钥"加密"公钥"解密"

    ---恢复内容开始---   之前工作主要使用C/C++与银行/第三方支付对接,但C/C++无法满足客户"当天给协议明天实盘上载"的开发速度以及现公司一些特殊情况,所以决定用go来 ...

  9. RSA 签名、验证、加密、解密帮助类

    import java.io.IOException; import java.security.InvalidKeyException; import java.security.KeyFactor ...

  10. NetCore 生成RSA公私钥对,公钥加密私钥解密,私钥加密公钥解密

    using Newtonsoft.Json; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Encodings; using ...

随机推荐

  1. uniapp动态修改导航栏

    1.修改导航栏buttons 如图动态修改角标 <template> <view> </view> </template> <script> ...

  2. WPF中修改ListBox项的样式病修改选中项的背景颜色

    最终效果: 1 <ListBox Name="cmb"> 2 <!--修改颜色--> 3 <ListBox.Resources> 4 <! ...

  3. .NET 编码的基础知识

    .NET 编码的一些基本概念和分析 简单的类型概念 Hex (16进制) byte 字节 范围是:0~255,二进制下的范围就是00000000~11111111,相当于1字节. byte[] 字节数 ...

  4. springboot配置health接口

    springboot配置health接口 spring-boot-starter-actuator 健康监控配置及使用 这样是可以看到一些结果的 如果在配置文件中用了下面这个,也是可以生效的 # 不进 ...

  5. .net core在linux下图片中文乱码

    不得不吐槽一下,.net core 2.2的System.Drawing在linux有很多坑,又是依赖libgdiplus,又是依赖gdiplus,依赖解决了又来了个中文乱码,怎的一声哀叹 这里做个笔 ...

  6. html基础 表格的相关属性使用

    1.1表格的基本标签 语法结构:<table> /*整体包裹部分,包裹多个tr */ <tr> /* 表格的每一个行,包裹td */ <td></td> ...

  7. pytest用例的执行顺序

    Pytest执行的顺序 当pytest运行测试函数时,它会查看该测试函数中的参数,然后搜索与这些参数具有相同名称的fixture.一旦pytest找到这些对象,它就会运行这些fixture 影响执行顺 ...

  8. Python中*args 和**kwargs作为形参和实参时的功能详解

    *args 和**kwargs作为形参 *args 和**kwargs作为形参被称为不定长参数,用来处理超出必备参数部分的参数.注意:args和kwargs可以修改为其它变量名. 必备参数就是在定义函 ...

  9. Nginx高并发简单配置

    https://www.cnblogs.com/sunjianguo/p/8298283.html 停用除SSH外的所有服务,仅保留nginx,优化思路主要包括两个层面:系统层面+nginx层面. 1 ...

  10. PowerShell 管道符之Where-Object的使用方法

    1 Get-Process|Select-Object -Property Name|Where-Object{$_ -match 'QQ'} 可以匹配到QQ为名的结果