一、背景
最近一项目采用分层架构,前端是Php,后端是Java,一些敏感数据传输采用加密处理,中间调试起来也是非常麻烦,因为每个语言实现的不一样,Php因为语言层面已经封装了,使用起来不用关注太多,但要了解原理就得看C语言写的代码了,反过来Java的实现就繁琐一些,对使用者不太友好,不过相对来说也比较容易了解原理了。
二、生成Key
linux生成公钥和密钥主要用到的工具是openssl,具体执行过程如下:
openssl genrsa -out rsa_private_key.pem 1024
openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out private_key.pem
openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
复制
第一条命令生成原始 RSA私钥文件 rsa_private_key.pem;
第二条命令将原始 RSA私钥转换为 pkcs8格式;
第三条生成RSA公钥 rsa_public_key.pem;
最后的key大概是这样的:
三、Php加密
Php代码比较简单,语言层面已经提供相应函数:
function rsaEncrypt($rawStr){
$publicKey = file_get_contents('/data/xxx/app/config/rsa_public_key.pem');
$key = openssl_pkey_get_public($publicKey);
$encrypted = '';
base64_encode(openssl_public_encrypt($rawStr, $encrypted ,$key));
return $encrypted;
}
复制
先获取公钥,然后调用openssl_pkey_get_public生成相应格式的公钥,再调用openssl_public_encrypt加密后再用base64加密下,保证出来的结果可读性好一点,不会是二进制字符串。
四、Java解密
class RsaDecryptor{
//根据私钥字符串生成密钥Key
public static PrivateKey genBase64PrivateKey(String privateKeyStr) throws Exception {
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyStr.getBytes()));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePrivate(pkcs8EncodedKeySpec);
}
//解密
public static String decrypt(String encryptedStr, PrivateKey key){
Cipher cipher = Cipher.getInstance("RSA/NONE/OAEPPadding");
cipher.init(2, key);
return doDecrypt(cipher, Base64.decodeBase64(ciphertext.getBytes()));
}
private static String doDecrypt(Cipher cipher, byte[] ciphertext) throws Exception {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
int len = ciphertext.length;
int blockCount = 0;
for(int offset = 0; len - offset > 0; offset = blockCount * 128) {
byte[] buffer;
if(len - offset > 128) {
buffer = cipher.doFinal(ciphertext, offset, 128);
} else {
buffer = cipher.doFinal(ciphertext, offset, len - offset);
}
byteArrayOutputStream.write(buffer, 0, buffer.length);
++blockCount;
}
byte[] decryptedDate = byteArrayOutputStream.toByteArray();
byteArrayOutputStream.close();
return new String(decryptedDate);
}
}
复制
上面是一个工具类,这里只是为了简单使用,所以全部使用了静态函数,具体使用如下:
String privateKey = "abc";
PrivateKey key = RsaDecryptor.genBase64PrivateKey(privateKey);
RsaDecryptor.decrypt("加密字符串", key);
复制
即先拿到私钥,再进行解密。
这里要注意一点,上面openssl生成私钥的时候格式是这样的:
-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQDQxvhGw9qrUO5U9FM3J7zgyikG6Fqj48kJf8hWaxUcZaBx9X1g
6i/JVXshkoXYBfE0EKKpPOOUy0uibAS+88rUGEWLVlozXpqVAVE3fArh/qy/yfva
RwVlZLD7JpqDdGmpLq2tj8hv7BnOsVKq0Vw2Umn+fmHViC4dHtd/O4FbswIDAQAB
AoGAOcpp3UTHmdZsMo3zHvhb+ylak/PrayRZeMyrSuiXTmX/NKxMiXApzCRiUhe5
/uMeMlhMfmZBZOWlSQ93fNgFE5JTCnP45yAtQ5eUd+JkXj3GujSeBFzqbrqJJh9+
e+aY0jrKGoYa+Z2xq966luyJJFX6Cv2ajZeC+xb8tsa1PFkCQQD4x08z09RaSjxm
4vZ/3OaWKh8RSXoGEfo8IutXIdWOICGds+zGbHFBDaySUGiSHD9Avyrgg3JkMEjM
pV8pIqE1AkEA1tZoZyxWVkh5nNfJ3s9FBt86mr+nxc0VCQf6NeKqo3yIGAxDX4PD
9EE2peG8ew3icz6FGrFlfw9rDGNZpDbORwJBAOYGu+gLBH1byM/FKfD+GsNcPQ+p
5cb5FmxGSV5ubVyVvx9nPxYVLP7emuNKr/XxYlcGq6meQMX8k0ON4RhS6cUCQQCE
hjBS7JO5l+2E5cv+KKdw7MTu7qjkqHSAZK5hDRirzsb45p+szNBU3OGEBDLLSa5V
3swmwiVU8sLbGnISjUhDAkEApiEbjkYMz6X9nvrB7Flk7C0unwcl0DbhNpwiiVdu
u5PYNflWbOiI5zUBsWyKnUi8Ni52tJXbltZkY+O7UA7PRg==
-----END RSA PRIVATE KEY-----
复制
我们要把最上面的begin和end这行去掉,还有中间的key是换行的,把换行符也要去掉,上面去掉之后最终的格式如下:
MIICXgIBAAKBgQDQxvhGw9qrUO5U9FM3J7zgyikG6Fqj48kJf8hWaxUcZaBx9X1g6i/JVXshkoXYBfE0EKKpPOOUy0uibAS+88rUGEWLVlozXpqVAVE3fArh/qy/yfvaRwVlZLD7JpqDdGmpLq2tj8hv7BnOsVKq0Vw2Umn+fmHViC4dHtd/O4FbswIDAQABAoGAOcpp3UTHmdZsMo3zHvhb+ylak/PrayRZeMyrSuiXTmX/NKxMiXApzCRiUhe5/uMeMlhMfmZBZOWlSQ93fNgFE5JTCnP45yAtQ5eUd+JkXj3GujSeBFzqbrqJJh9+e+aY0jrKGoYa+Z2xq966luyJJFX6Cv2ajZeC+xb8tsa1PFkCQQD4x08z09RaSjxm4vZ/3OaWKh8RSXoGEfo8IutXIdWOICGds+zGbHFBDaySUGiSHD9Avyrgg3JkMEjMpV8pIqE1AkEA1tZoZyxWVkh5nNfJ3s9FBt86mr+nxc0VCQf6NeKqo3yIGAxDX4PD9EE2peG8ew3icz6FGrFlfw9rDGNZpDbORwJBAOYGu+gLBH1byM/FKfD+GsNcPQ+p5cb5FmxGSV5ubVyVvx9nPxYVLP7emuNKr/XxYlcGq6meQMX8k0ON4RhS6cUCQQCEhjBS7JO5l+2E5cv+KKdw7MTu7qjkqHSAZK5hDRirzsb45p+szNBU3OGEBDLLSa5V3swmwiVU8sLbGnISjUhDAkEApiEbjkYMz6X9nvrB7Flk7C0unwcl0DbhNpwiiVduu5PYNflWbOiI5zUBsWyKnUi8Ni52tJXbltZkY+O7UA7PRg==
复制
文章转载自程序员升级之路,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。