Base64、MD5、RSA和ASE加密算法总结及JAVA实现-RSA
程序员文章站
2024-03-20 09:58:34
...
常见加密算法
常见的加密算法可以分成三类,对称加密算法,非对称加密算法和Hash算法。
非对称加密算法
非对称加密算法需要两个**:公开**(publickey)和私有**(privatekey)。公开**与私有**是一对,如果用公开**对数据进行加密,只有用对应的私有**才能解密;如果用私有**对数据进行加密,那么只有用对应的公开**才能解密。因为加密和解密使用的是两个不同的**,所以这种算法叫作非对称加密算法。
常见的非对称算法包括了:RSA、Elgamal等算法。
RSA算法
RSA是目前最有影响力的公钥加密算法,该算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加***,即公钥,而两个大素数组合成私钥。公钥是可发布的供任何人使用,私钥则为自己所有,供解密之用。
过程:
- 随意选择两个大的质数p和q,p不等于q,计算N=pq。
- 根据欧拉函数,不大于N且与N互质的整数個数為(p-1)(q-1)。
- 选择一个整数e与(p-1)(q-1)互质,并且e小于(p-1)(q-1)。
- 用以下这个公式计算d:d× e ≡ 1 (mod (p-1)(q-1))。
- 将p和q的记录销毁。
(N,e)是公钥,(N,d)是私钥。
JAVA实现
public class RSAUtils {
public static final String CHARSET = "UTF-8";
public static final String RSA_ALGORITHM = "RSA";
public static Map<String, String> createKeys(int keySize){
//为RSA算法创建一个KeyPairGenerator对象
KeyPairGenerator kpg;
try{
kpg = KeyPairGenerator.getInstance(RSA_ALGORITHM);
}catch(NoSuchAlgorithmException e){
throw new IllegalArgumentException("No such algorithm-->[" + RSA_ALGORITHM + "]");
}
//初始化KeyPairGenerator对象,**长度
kpg.initialize(keySize);
//生成密匙对
KeyPair keyPair = kpg.generateKeyPair();
//得到公钥
Key publicKey = keyPair.getPublic();
//Base64编码
String publicKeyStr = Base64Utils.getEncoder().encodeToString(publicKey.getEncoded());
//得到私钥
Key privateKey = keyPair.getPrivate();
//Base64编码
String privateKeyStr = Base64Utils.getEncoder().encodeToString(privateKey.getEncoded());
Map<String, String> keyPairMap = new HashMap<String, String>();
keyPairMap.put("publicKey", publicKeyStr);
keyPairMap.put("privateKey", privateKeyStr);
return keyPairMap;
}
/**
* 得到公钥
* @param publicKey **字符串(经过base64编码)
* @throws Exception
*/
public static RSAPublicKey getPublicKey(String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
//通过X509编码的Key指令获得公钥对象
KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
//Base64解码
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec( Base64Utils.getDecoder().decode(publicKey));
RSAPublicKey key = (RSAPublicKey) keyFactory.generatePublic(x509KeySpec);
return key;
}
/**
* 得到私钥
* @param privateKey **字符串(经过base64编码)
* @throws Exception
*/
public static RSAPrivateKey getPrivateKey(String privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
//通过PKCS#8编码的Key指令获得私钥对象
KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
//Base64解码
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64Utils.getDecoder().decode(privateKey));
RSAPrivateKey key = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8KeySpec);
return key;
}
/**
* 公钥加密
* @param data
* @param publicKey
* @return
*/
public static String publicEncrypt(String data, RSAPublicKey publicKey){
try{
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return Base64Utils.getEncoder().encodeToString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET), publicKey.getModulus().bitLength()));
}catch(Exception e){
throw new RuntimeException("加密数据:" + data + ",发生异常", e);
}
}
/**
* 私钥解密
* @param data
* @param privateKey
* @return
*/
public static String privateDecrypt(String data, RSAPrivateKey privateKey){
try{
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64Utils.getDecoder().decode(data), privateKey.getModulus().bitLength()), CHARSET);
}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("加解密数据时发生异常", e);
}finally {
try {
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
byte[] resultDatas = out.toByteArray();
return resultDatas;
}
}