一、背景
最近一项目采用分层架构,前端是Php,后端是Java,一些敏感数据传输采用加密处理,中间调试起来也是非常麻烦,因为每个语言实现的不一样,Php因为语言层面已经封装了,使用起来不用关注太多,但要了解原理就得看C语言写的代码了,反过来Java的实现就繁琐一些,对使用者不太友好,不过相对来说也比较容易了解原理了。
二、生成Key
linux生成公钥和密钥主要用到的工具是openssl,具体执行过程如下:
openssl genrsa -out rsa_private_key.pem 1024openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out private_key.pemopenssl 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{//根据私钥字符串生成密钥Keypublic 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-----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==-----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进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




