首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Php和Java之间RSA加解密实战

Php和Java之间RSA加解密实战

作者头像
心平气和
发布2021-04-01 17:04:32
发布2021-04-01 17:04:32
1.3K0
举报

一、背景

最近一项目采用分层架构,前端是Php,后端是Java,一些敏感数据传输采用加密处理,中间调试起来也是非常麻烦,因为每个语言实现的不一样,Php因为语言层面已经封装了,使用起来不用关注太多,但要了解原理就得看C语言写的代码了,反过来Java的实现就繁琐一些,对使用者不太友好,不过相对来说也比较容易了解原理了。

二、生成Key

linux生成公钥和密钥主要用到的工具是openssl,具体执行过程如下:

代码语言:javascript
复制
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代码比较简单,语言层面已经提供相应函数:

代码语言:javascript
复制
   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解密

代码语言:javascript
复制
 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);    }    }

上面是一个工具类,这里只是为了简单使用,所以全部使用了静态函数,具体使用如下:

代码语言:javascript
复制
String privateKey = "abc";PrivateKey key = RsaDecryptor.genBase64PrivateKey(privateKey);RsaDecryptor.decrypt("加密字符串", key);

即先拿到私钥,再进行解密。

这里要注意一点,上面openssl生成私钥的时候格式是这样的:

代码语言:javascript
复制
-----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是换行的,把换行符也要去掉,上面去掉之后最终的格式如下:

代码语言:javascript
复制
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==
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-03-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员升级之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档