Created
August 11, 2021 14:20
-
-
Save yunkaiOr2/0af2892d9d972fca41126b68744ec10f to your computer and use it in GitHub Desktop.
rsa script groovy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package tools; | |
import org.apache.commons.io.IOUtils; | |
import org.apache.commons.codec.binary.Base64; | |
import javax.crypto.Cipher; | |
import java.io.ByteArrayOutputStream; | |
import java.security.*; | |
import java.security.interfaces.RSAPrivateKey; | |
import java.security.interfaces.RSAPublicKey; | |
import java.security.spec.InvalidKeySpecException; | |
import java.security.spec.PKCS8EncodedKeySpec; | |
import java.security.spec.X509EncodedKeySpec; | |
import java.util.HashMap; | |
import java.util.Map; | |
/** | |
* 分段加密,无数据大小限制 | |
*/ | |
public class XRsa { | |
public static final String CHARSET = "UTF-8"; | |
public static final String RSA_ALGORITHM = "RSA"; | |
public static final String RSA_ALGORITHM_SIGN = "SHA256WithRSA"; | |
private RSAPublicKey publicKey; | |
private RSAPrivateKey privateKey; | |
public static final class Builder { | |
private RSAPublicKey publicKey; | |
private RSAPrivateKey privateKey; | |
public Builder setPublicKey(String publicKeyStr) { | |
try { | |
KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM); | |
//通过X509编码的Key指令获得公钥对象 | |
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyStr)); | |
this.publicKey = (RSAPublicKey) keyFactory.generatePublic(x509KeySpec); | |
} catch (Exception e) { | |
throw new RuntimeException("不支持的密钥", e); | |
} | |
return this; | |
} | |
public Builder setPrivateKey(String privateKeyStr) { | |
try { | |
KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM); | |
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyStr)); | |
this.privateKey = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8KeySpec); | |
} catch (Exception e) { | |
throw new RuntimeException("不支持的密钥", e); | |
} | |
return this; | |
} | |
public XRsa build() { | |
XRsa xRsa = new XRsa(); | |
xRsa.setPrivateKey(privateKey); | |
xRsa.setPublicKey(publicKey); | |
return xRsa; | |
} | |
} | |
public static Builder createBuilder() { | |
return new Builder(); | |
} | |
public static Map<String, String> createKeys(int keySize){ | |
//为RSA算法创建一个KeyPairGenerator对象 | |
KeyPairGenerator kpg; | |
try{ | |
kpg = KeyPairGenerator.getInstance(RSA_ALGORITHM, "BC"); | |
}catch(Exception e){ | |
throw new IllegalArgumentException("No such algorithm-->[" + RSA_ALGORITHM + "]"); | |
} | |
//初始化KeyPairGenerator对象,不要被initialize()源码表面上欺骗,其实这里声明的size是生效的 | |
kpg.initialize(keySize); | |
//生成密匙对 | |
KeyPair keyPair = kpg.generateKeyPair(); | |
//得到公钥 | |
Key publicKey = keyPair.getPublic(); | |
String publicKeyStr = Base64.encodeBase64URLSafeString(publicKey.getEncoded()); | |
//得到私钥 | |
Key privateKey = keyPair.getPrivate(); | |
String privateKeyStr = Base64.encodeBase64URLSafeString(privateKey.getEncoded()); | |
Map<String, String> keyPairMap = new HashMap<String, String>(); | |
keyPairMap.put("publicKey", publicKeyStr); | |
keyPairMap.put("privateKey", privateKeyStr); | |
return keyPairMap; | |
} | |
public String publicEncrypt(String data){ | |
try{ | |
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM); | |
cipher.init(Cipher.ENCRYPT_MODE, publicKey); | |
return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET), publicKey.getModulus().bitLength())); | |
}catch(Exception e){ | |
throw new RuntimeException("加密字符串[" + data + "]时遇到异常", e); | |
} | |
} | |
public String privateDecrypt(String data){ | |
try{ | |
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM); | |
cipher.init(Cipher.DECRYPT_MODE, privateKey); | |
return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data), publicKey.getModulus().bitLength()), CHARSET); | |
}catch(Exception e){ | |
throw new RuntimeException("解密字符串[" + data + "]时遇到异常", e); | |
} | |
} | |
public String privateEncrypt(String data){ | |
try{ | |
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM); | |
cipher.init(Cipher.ENCRYPT_MODE, privateKey); | |
return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET), publicKey.getModulus().bitLength())); | |
}catch(Exception e){ | |
throw new RuntimeException("加密字符串[" + data + "]时遇到异常", e); | |
} | |
} | |
public String publicDecrypt(String data){ | |
try{ | |
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM); | |
cipher.init(Cipher.DECRYPT_MODE, publicKey); | |
return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data), publicKey.getModulus().bitLength()), CHARSET); | |
}catch(Exception e){ | |
throw new RuntimeException("解密字符串[" + data + "]时遇到异常", e); | |
} | |
} | |
public String sign(String data){ | |
try{ | |
//sign | |
Signature signature = Signature.getInstance(RSA_ALGORITHM_SIGN); | |
signature.initSign(privateKey); | |
signature.update(data.getBytes(CHARSET)); | |
return Base64.encodeBase64URLSafeString(signature.sign()); | |
}catch(Exception e){ | |
throw new RuntimeException("签名字符串[" + data + "]时遇到异常", e); | |
} | |
} | |
public boolean verify(String data, String sign){ | |
try{ | |
Signature signature = Signature.getInstance(RSA_ALGORITHM_SIGN); | |
signature.initVerify(publicKey); | |
signature.update(data.getBytes(CHARSET)); | |
return signature.verify(Base64.decodeBase64(sign)); | |
}catch(Exception e){ | |
throw new RuntimeException("验签字符串[" + data + "]时遇到异常", e); | |
} | |
} | |
private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int keySize){ | |
int maxBlock = 0; | |
if(opmode == Cipher.DECRYPT_MODE){ | |
maxBlock = keySize / 8; | |
}else{ | |
maxBlock = keySize / 8 - 11; | |
} | |
ByteArrayOutputStream out = new ByteArrayOutputStream(); | |
int offSet = 0; | |
byte[] buff; | |
int i = 0; | |
try{ | |
while(datas.length > offSet){ | |
if(datas.length - offSet > maxBlock){ | |
buff = cipher.doFinal(datas, offSet, maxBlock); | |
} else { | |
buff = cipher.doFinal(datas, offSet, datas.length - offSet); | |
} | |
out.write(buff, 0, buff.length); | |
i++; | |
offSet = i * maxBlock; | |
} | |
}catch(Exception e){ | |
throw new RuntimeException("加解密阀值为["+maxBlock+"]的数据时发生异常", e); | |
} | |
byte[] resultDatas = out.toByteArray(); | |
IOUtils.closeQuietly(out); | |
return resultDatas; | |
} | |
public void setPublicKey(RSAPublicKey publicKey) { | |
this.publicKey = publicKey; | |
} | |
public void setPrivateKey(RSAPrivateKey privateKey) { | |
this.privateKey = privateKey; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment