RSA密文过长加密解密 越过1024的解决代码

2019-07-16 13:00:32 浏览数 (1)

什么是RSA加密?

RSA (详见维基百科)算法是现今使用最广泛的公钥密码算法,也是号称地球上最安全的加密算法,与 md5 和 sha1 不同,到目前为止,也只有极短的RSA加密被破解。

使用场景

  • 为移动端(IOS,安卓)编写 API 接口
  • 进行支付、真实信息验证等安全性需求较高的通信
  • 与其他第三方或合作伙伴进行重要的数据传输,用于外部商户系统和本系统之间报文的安全性验证。

生成私钥、公钥

1、生成原始 RSA 私钥文件

代码语言:javascript复制
1openssl genrsa -out private_key.pem 1024

说明:生成RSA私钥,private_key.pem 为存放私钥的文件名,长度1204

2、将原始 RSA 私钥转换为 pkcs8 格式

代码语言:javascript复制
1openssl pkcs8 -topk8 -inform PEM -in private_key.pem -outform PEM -nocrypt -out rsa_private_key.pem

说明:把RSA私钥转换成PKCS8格式,转化后的私钥 rsa_private_key.pem

3、生成 RSA 公钥

代码语言:javascript复制
1openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

说明:生成RSA公钥文件rsa_public_key.pem

4、最后会有三个文件

代码语言:javascript复制
1λ ls
2private_key.pem  rsa_private_key.pem  rsa_public_key.pem

文本打开rsa_private_key.pemrsa_public_key.pem,里面存放的是私钥、公钥。商户需要把公钥字符串发给易付宝的业务人员,私钥商户自行保存。

php-rsa 加密解密

Rsa 服务器类库

代码语言:javascript复制
  1<?php
  2/**.-------------------------------------------------------------------------------------------------------------------
  3 * |  Github: https://github.com/Tinywan
  4 * |  Blog: http://www.cnblogs.com/Tinywan
  5 * |--------------------------------------------------------------------------------------------------------------------
  6 * |  Author: Tinywan(ShaoBo Wan)
  7 * |  DateTime: 2018/8/30 22:48
  8 * |  Mail: 756684177@qq.com
  9 * |  Desc: php-rsa 加密解密 https://segmentfault.com/a/1190000012083428
 10 * '------------------------------------------------------------------------------------------------------------------*/
 11
 12namespace appcommonlibrary;
 13
 14
 15class Rsa
 16{
 17    /**
 18     * @var array 默认配置
 19     */
 20    private $_config = [
 21        'public_key' => '-----BEGIN PUBLIC KEY-----
 22MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCbtLA7lMfUvpBgfgzouiPgcnbL
 23DnEcuCK0gMub/EAEqmr82sl 9tH1iQb1w/hgQLptVRxAuUOa03XqlnG3wkAegtQt
 244Q5ZtHSSomE8/5FXJvQfGTCz5RARyM0MiLTMZJGhLdVT6O8uCYIrPRQq7u6NVLs9
 256YDmtzX2do/sTsWCAwIDAQAB
 26-----END PUBLIC KEY-----',
 27        'private_key' => '-----BEGIN RSA PRIVATE KEY-----
 28MIICWwIBAAKBgQCbtLA7lMfUvpBgfgzouiPgcnbLDnEcuCK0gMub/EAEqmr82sl 
 299tH1iQb1w/hgQLptVRxAuUOa03XqlnG3wkAegtQt4Q5ZtHSSomE8/5FXJvQfGTCz
 305RARyM0MiLTMZJGhLdVT6O8uCYIrPRQq7u6NVLs96YDmtzX2do/sTsWCAwIDAQAB
 31AoGAfnO3zCuAPp6k0jiMc1T4XgeXwkDwS8qfJMiUkxHBTAi66q8khSAeU7H9HQsS
 32Y9ktji1YzJeo98xULzgPEpWHS/uhA8VZa16TLy9Yfadn2t wpWpEJ9ZA4jjEqfQj
 33DDxcUc/pEv5siaE/bU8uls4o2nAiuWnI2n5FGrQa2OziGUECQQDPOh3KD2AOZtEF
 34p7i0yxYXe4dCKwenfw5q7l933RgqMXsVR1EAGzAUdIs71hTye6ibhva eJRfndoV
 35Jq2IHjOdAkEAwFpOZR8j3Cl4zEk/9D9WEnSa8VWLe76vb7DfgfwkSAhs/f2MNF1I
 36zy9W5tPHRiMzaHNgPBFX9tw2u5QzsgOqHwJAPl3zUTjHZA41okoUIPVuNKsMzjE9
 37IH/wyuXq/ZwhBbHWpVTNYAbOtZlNvjh0HXZyDDzWTgTkQtKzK J0H59XUQJARukD
 38vYOdVKx1O9pFGWW/9U3HUPCYWyYQxrwNqX2qYmO4ymmOJj 9d6OcBbxM2i5f5UGj
 39WIGMTBUimEQqSpXPQQJAIkHC2GknUv8HaBRLXxYTIAjj78a0pQT2bYlI6R04AwUZ
 40ljBaUGvvdYJ3CGZ32Xk12Te2fMJj5h/yLyEr8uzpzw==
 41-----END RSA PRIVATE KEY-----',
 42    ];
 43
 44    /**
 45     * 构造函数
 46     * Rsa constructor.
 47     * @param $private_key_filepath
 48     * @param $public_key_filepath
 49     */
 50    public function __construct($private_key_filepath = null, $public_key_filepath = null)
 51    {
 52        if(!empty($private_key_filepath) && !empty($public_key_filepath)){
 53            $this->_config['private_key'] = $this->_getContents($private_key_filepath);
 54            $this->_config['public_key'] = $this->_getContents($public_key_filepath);
 55        }
 56    }
 57
 58    /**
 59     * @uses 获取文件内容
 60     * @param $file_path string
 61     * @return bool|string
 62     */
 63    private function _getContents($file_path)
 64    {
 65        file_exists($file_path) or die ('密钥或公钥的文件路径错误');
 66        return file_get_contents($file_path);
 67    }
 68
 69    /**
 70     * @uses 获取私钥
 71     * @return bool|resource
 72     */
 73    private function _getPrivateKey()
 74    {
 75        $private_key = $this->_config['private_key'];
 76        return openssl_pkey_get_private($private_key);
 77    }
 78
 79    /**
 80     * @uses 获取公钥
 81     * @return bool|resource
 82     */
 83    private function _getPublicKey()
 84    {
 85        $public_key = $this->_config['public_key'];
 86        return openssl_pkey_get_public($public_key);
 87    }
 88
 89    /**
 90     * 私钥加密 (使用公钥解密)
 91     * @param string $data
 92     * @return null|string
 93     */
 94    public function privateEncrypt($data = '', $padding = OPENSSL_PKCS1_PADDING)
 95    {
 96        if (!is_string($data)) return null;
 97        $encrypted = '';
 98        $chunks = str_split($data, 117);
 99        foreach ($chunks as $chunk) {
100            $partialEncrypted = '';
101            $encryptionOk = openssl_private_encrypt($chunk, $partialEncrypted, $this->_getPrivateKey(), $padding);
102            if ($encryptionOk === false) {
103                return null;
104            }
105            $encrypted .= $partialEncrypted;
106        }
107        $encrypted = base64_encode($encrypted);
108        return $encrypted;
109    }
110
111    /**
112     * 公钥加密(使用私钥解密)
113     * @param string $data 加密字符串
114     * @param int $padding
115     * @return null|string
116     */
117    public function publicEncrypt($data = '', $padding = OPENSSL_PKCS1_PADDING)
118    {
119        if (!is_string($data)) return null;
120        $encrypted = '';
121        $chunks = str_split($data, 117);
122        foreach ($chunks as $chunk) {
123            $partialEncrypted = '';
124            $encryptionOk = openssl_public_encrypt($chunk, $partialEncrypted, $this->_getPublicKey(), $padding);
125            if ($encryptionOk === false) {
126                return null;
127            }
128            $encrypted .= $partialEncrypted;
129        }
130        $encrypted = base64_encode($encrypted);
131        return $encrypted;
132    }
133
134    /**
135     * @uses 私钥解密 (使用公钥加密)
136     * @param string $encrypted
137     * @return null
138     */
139    public function privateDecrypt($encrypted = '')
140    {
141        if (!is_string($encrypted)) return null;
142        $decrypted = '';
143        $chunks = str_split(base64_decode($encrypted), 128);
144        foreach ($chunks as $chunk) {
145            $partial = '';
146            $decryptIsTrue = openssl_private_decrypt($chunk, $partial, $this->_getPrivateKey());
147            if ($decryptIsTrue === false) {
148                return null;
149            }
150            $decrypted .= $partial;
151        }
152        return $decrypted;
153    }
154
155    /**
156     * 公钥解密 (使用私钥解密)
157     * @param string $encrypted 被解密字符串
158     * @return null
159     */
160    public function publicDecrypt($encrypted = '')
161    {
162        if (!is_string($encrypted)) return null;
163        $decrypted = '';
164        $chunks = str_split(base64_decode($encrypted), 128);
165        foreach ($chunks as $chunk) {
166            $partial = '';
167            $decryptIsTrue = openssl_public_decrypt($chunk, $partial, $this->_getPublicKey());
168            if ($decryptIsTrue === false) {
169                return null;
170            }
171            $decrypted .= $partial;
172        }
173        return $decrypted;
174    }
175
176    /**
177     * 私钥验签
178     * @param $data string 验签内容
179     * @param $signature string 签名字符串
180     * @param int $signature_alg
181     * @return bool
182     */
183    public function privateSign($data, $signature, $signature_alg = OPENSSL_ALGO_SHA1)
184    {
185        $result = openssl_sign($data, base64_decode($signature), $this->_getPrivateKey(), $signature_alg);
186        openssl_free_key($this->_getPrivateKey());
187        return $result === 1 ? true : false;
188    }
189
190    /**
191     * 公钥验签
192     * @param $data string 验签内容
193     * @param $signature string 签名字符串
194     * @param int $signature_alg
195     * @return bool
196     */
197    public function publicSign($data, $signature, $signature_alg = OPENSSL_ALGO_SHA1)
198    {
199        $result = openssl_verify($data, base64_decode($signature), $this->_getPublicKey(), $signature_alg);
200        openssl_free_key($this->_getPublicKey());
201        return $result === 1 ? true : false;
202    }
203}
204

使用案例

  • 公钥加密、私钥解密
代码语言:javascript复制
 1$rsa = new Rsa();
 2// 加密明文
 3$crypt_text = '公钥加密、私钥解密';
 4echo '加密明文:' . $crypt_text.PHP_EOL;
 5
 6$public_encrypt_data = $rsa->publicEncrypt($crypt_text);
 7echo '公钥加密后数据:' . $public_encrypt_data.PHP_EOL; // 一直在变化
 8
 9$private_decrypt_data = $rsa->privateDecrypt($public_encrypt_data);
10echo '私钥解密数据: ' . $private_decrypt_data.PHP_EOL;

加密明文:公钥加密、私钥解密 公钥加密后数据:QHdj15P6l1gJbjNlD7spKT7KjCJJ0Qg5c8JjLBAS9hvhkq8eRuaNY/dDrboD3t40NvyPI8SBFBkDTjJ5IDyqTTSfthUROvasMD7wCPRYGaOt5to ygfvV5t4CyYQEvSSflqimWvffRs0L8fs3pqE2kLD/AHOC94 ZBNFfzTTtVA= 私钥解密数据: 公钥加密、私钥解密

  • 私钥加密、公钥解密
代码语言:javascript复制
 1$rsa = new Rsa();
 2// 加密明文
 3$crypt_text = '私钥加密、公钥解密';
 4echo '加密明文:' . $crypt_text.PHP_EOL;
 5
 6$private_encrypt_data = $rsa->privateEncrypt($crypt_text);
 7echo '私钥加密后数据:' . $private_encrypt_data..PHP_EOL; // 不变
 8
 9$public_decrypt_data = $rsa->publicDecrypt($private_encrypt_data);
10echo '公钥解密数据: ' . $public_decrypt_data..PHP_EOL;

加密明文:私钥加密、公钥解密 私钥加密后数据:dDzAs7kj9z7kS7Zbcz6sNLP sIOnXp2qFGr4RepZcZp9XzCt8Tt Kd/NIo4S20hjAvBiurvSHaR6LLL5ur5dc4vkFGkV bGaT2SlhC4JkvYt4N2T9EiQupwcCtlk dcENLexWiCvZtuzk3peK H7AUWqFeOlmGRZb3De7bP heY= 公钥解密数据: 私钥加密、公钥解密

  • 测试结果:私钥加密是不变的,公钥加密后的字符串一直是变化的

0 人点赞