mirror of
https://gitee.com/jzsw-it/yexuejc-base.git
synced 2025-06-06 22:04:04 +08:00
1.2.2 增加RSA签名
This commit is contained in:
parent
286c65b868
commit
3ba0e22e65
@ -1,6 +1,13 @@
|
||||
yexuejc-base 更新记录
|
||||
------------------
|
||||
|
||||
#### version :1.2.2
|
||||
**time:2018-11-20 20:20:12** <br/>
|
||||
**branch:** master <br/>
|
||||
**update:** <br/>
|
||||
>1. 优化RSA 加解密
|
||||
>1. 增加RSA 签名
|
||||
#
|
||||
#### version :1.2.1
|
||||
**time:2018-11-9 15:05:06** <br/>
|
||||
**branch:** master <br/>
|
||||
|
2
pom.xml
2
pom.xml
@ -6,7 +6,7 @@
|
||||
|
||||
<groupId>com.yexuejc.base</groupId>
|
||||
<artifactId>yexuejc-base</artifactId>
|
||||
<version>1.2.1</version>
|
||||
<version>1.2.2</version>
|
||||
|
||||
<name>${project.artifactId}</name>
|
||||
|
||||
|
@ -3,9 +3,12 @@ package com.yexuejc.base.encrypt;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.*;
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
@ -27,6 +30,25 @@ public class RSA {
|
||||
|
||||
public static final String CHARSET = "UTF-8";
|
||||
public static final String RSA_ALGORITHM = "RSA";
|
||||
/**
|
||||
* 加密方式
|
||||
* <pre>
|
||||
* RSA 可选择isChangeSign 是否每次改变加密结果
|
||||
* RSA/None/NoPadding 不改变加密结果
|
||||
* RSA/ECB/PKCS1Padding 改变加密结果
|
||||
* </pre>
|
||||
*/
|
||||
public static String RSA_ALGORITHM_ECB = "RSA";
|
||||
/**
|
||||
* 是否每次改变加密结果
|
||||
* 只针对于RSA_ALGORITHM_ECB = "RSA"有效
|
||||
*/
|
||||
public static boolean isChangeSign = true;
|
||||
/**
|
||||
* 签名算法
|
||||
*/
|
||||
public static SignAlgorithm signAlgorithm = SignAlgorithm.SHA1withRSA;
|
||||
|
||||
|
||||
public static Map<String, String> initKeys(int keySize) {
|
||||
//为RSA算法创建一个KeyPairGenerator对象
|
||||
@ -61,7 +83,7 @@ public class RSA {
|
||||
* @param publicKey 密钥字符串(经过base64编码)
|
||||
* @throws Exception
|
||||
*/
|
||||
public static RSAPublicKey getPublicKey(String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||
public static RSAPublicKey getPublicKey(String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException{
|
||||
//通过X509编码的Key指令获得公钥对象
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
|
||||
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKey));
|
||||
@ -92,7 +114,7 @@ public class RSA {
|
||||
*/
|
||||
public static String publicEncrypt(String data, RSAPublicKey publicKey) {
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
|
||||
Cipher cipher = getCipher();
|
||||
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
||||
return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET), publicKey.getModulus().bitLength()));
|
||||
} catch (Exception e) {
|
||||
@ -109,7 +131,7 @@ public class RSA {
|
||||
*/
|
||||
public static String privateDecrypt(String data, RSAPrivateKey privateKey) {
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
|
||||
Cipher cipher = getCipher();
|
||||
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
||||
return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data), privateKey.getModulus().bitLength()), CHARSET);
|
||||
} catch (Exception e) {
|
||||
@ -117,6 +139,7 @@ public class RSA {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 私钥加密
|
||||
*
|
||||
@ -127,7 +150,7 @@ public class RSA {
|
||||
|
||||
public static String privateEncrypt(String data, RSAPrivateKey privateKey) {
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
|
||||
Cipher cipher = getCipher();
|
||||
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
|
||||
return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET), privateKey.getModulus().bitLength()));
|
||||
} catch (Exception e) {
|
||||
@ -145,7 +168,7 @@ public class RSA {
|
||||
|
||||
public static String publicDecrypt(String data, RSAPublicKey publicKey) {
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
|
||||
Cipher cipher = getCipher();
|
||||
cipher.init(Cipher.DECRYPT_MODE, publicKey);
|
||||
return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data), publicKey.getModulus().bitLength()), CHARSET);
|
||||
} catch (Exception e) {
|
||||
@ -153,6 +176,25 @@ public class RSA {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 Cipher
|
||||
*
|
||||
* @return
|
||||
* @throws NoSuchPaddingException
|
||||
* @throws NoSuchAlgorithmException
|
||||
* @throws NoSuchProviderException
|
||||
*/
|
||||
private static Cipher getCipher() throws NoSuchPaddingException, NoSuchAlgorithmException, NoSuchProviderException {
|
||||
Cipher cipher;
|
||||
if ("RSA".equals(RSA_ALGORITHM_ECB) && isChangeSign) {
|
||||
cipher = Cipher.getInstance(RSA_ALGORITHM_ECB);
|
||||
} else {
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
cipher = Cipher.getInstance(RSA_ALGORITHM_ECB, "BC");
|
||||
}
|
||||
return cipher;
|
||||
}
|
||||
|
||||
private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int keySize) {
|
||||
int maxBlock = 0;
|
||||
if (opmode == Cipher.DECRYPT_MODE) {
|
||||
@ -183,4 +225,66 @@ public class RSA {
|
||||
return resultDatas;
|
||||
}
|
||||
|
||||
private static Signature signature;
|
||||
|
||||
/**
|
||||
* 私钥签名:默认算法SHA1withRSA
|
||||
* <p>
|
||||
* 签名算法 {@link SignAlgorithm}
|
||||
* </p>
|
||||
*
|
||||
* @param plaintext 签名字符串
|
||||
* @param privateKey 签名私钥
|
||||
* @return
|
||||
* @throws NoSuchAlgorithmException
|
||||
*/
|
||||
public static String sign(String plaintext, RSAPrivateKey privateKey) throws NoSuchAlgorithmException {
|
||||
signature = Signature.getInstance(signAlgorithm.getValue());
|
||||
String signBase64Str = "";
|
||||
|
||||
try {
|
||||
signature.initSign(privateKey);
|
||||
try {
|
||||
signature.update(plaintext.getBytes(CHARSET));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("签名字符串[" + plaintext + "]的数据时发生异常", e);
|
||||
}
|
||||
|
||||
signBase64Str = Base64.encodeBase64String(signature.sign());
|
||||
return signBase64Str;
|
||||
} catch (InvalidKeyException var6) {
|
||||
var6.printStackTrace();
|
||||
throw new RuntimeException("签名字符串[" + plaintext + "]的数据时发生异常", var6);
|
||||
} catch (SignatureException var7) {
|
||||
var7.printStackTrace();
|
||||
throw new RuntimeException("签名字符串[" + plaintext + "]的数据时发生异常", var7);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 公钥校验签名
|
||||
*
|
||||
* @param plaintext 原串
|
||||
* @param signStr 签名串
|
||||
* @param publicKey 公钥
|
||||
* @return
|
||||
* @throws UnsupportedEncodingException
|
||||
*/
|
||||
public static boolean verify(String plaintext, String signStr, RSAPublicKey publicKey) throws UnsupportedEncodingException {
|
||||
boolean isValid = false;
|
||||
try {
|
||||
signature.initVerify(publicKey);
|
||||
signature.update(plaintext.getBytes(CHARSET));
|
||||
isValid = signature.verify(Base64.decodeBase64(signStr));
|
||||
} catch (InvalidKeyException var6) {
|
||||
var6.printStackTrace();
|
||||
throw new RuntimeException("校验签名字符串[" + plaintext + "]的数据时发生异常", var6);
|
||||
} catch (SignatureException var7) {
|
||||
var7.printStackTrace();
|
||||
throw new RuntimeException("校验签名字符串[" + plaintext + "]的数据时发生异常", var7);
|
||||
}
|
||||
|
||||
return isValid;
|
||||
}
|
||||
}
|
||||
|
53
src/main/java/com/yexuejc/base/encrypt/SignAlgorithm.java
Normal file
53
src/main/java/com/yexuejc/base/encrypt/SignAlgorithm.java
Normal file
@ -0,0 +1,53 @@
|
||||
package com.yexuejc.base.encrypt;
|
||||
|
||||
/**
|
||||
* 签名算法类型
|
||||
* 参考Hutool
|
||||
* see: https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#Signature
|
||||
*/
|
||||
public enum SignAlgorithm {
|
||||
// The RSA signature algorithm
|
||||
NONEwithRSA("NONEwithRSA"),
|
||||
|
||||
// The MD2/MD5 with RSA Encryption signature algorithm
|
||||
MD2withRSA("MD2withRSA"),
|
||||
MD5withRSA("MD5withRSA"),
|
||||
|
||||
// The signature algorithm with SHA-* and the RSA
|
||||
SHA1withRSA("SHA1withRSA"),
|
||||
SHA256withRSA("SHA256withRSA"),
|
||||
SHA384withRSA("SHA384withRSA"),
|
||||
SHA512withRSA("SHA512withRSA"),
|
||||
|
||||
// The Digital Signature Algorithm
|
||||
NONEwithDSA("NONEwithDSA"),
|
||||
// The DSA with SHA-1 signature algorithm
|
||||
SHA1withDSA("SHA1withDSA"),
|
||||
|
||||
// The ECDSA signature algorithms
|
||||
NONEwithECDSA("NONEwithECDSA"),
|
||||
SHA1withECDSA("SHA1withECDSA"),
|
||||
SHA256withECDSA("SHA256withECDSA"),
|
||||
SHA384withECDSA("SHA384withECDSA"),
|
||||
SHA512withECDSA("SHA512withECDSA");
|
||||
|
||||
private String value;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param value 算法字符表示,区分大小写
|
||||
*/
|
||||
private SignAlgorithm(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取算法字符串表示,区分大小写
|
||||
*
|
||||
* @return 算法字符串表示
|
||||
*/
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user