PHP使用OpenSSL加密

1.生成签名与验签

相关函数

openssl_get_privatekey() 获取私钥文件的内容
openssl_sign() 私钥生成签名
openssl_get_publickey() 获取公钥文件的内容
openssl_veriry() 公钥验证签名

生成公钥和私钥

常用的rsa密钥有两种格式:

  1. pkcs1格式
# 公钥
-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----
# 私钥
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
  1. pkcs8格式
# 公钥
-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----
# 私钥
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----

php中使用的是pkcs1格式的,java中使用的是pkcs8格式的,这里都做一下介绍。

下面开始生成公钥和私钥文件:

  1. 生成原始 RSA私钥文件 rsa_private_key.pem
openssl genrsa -out rsa_private_key.pem 1024
  1. 将原始 RSA私钥转换为 pkcs8格式,JAVA需要使用的私钥需要经过 PKCS8 编码
openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out rsa_private_key_java.pem
  1. 生成 RSA公钥 rsa_public_key.pem
openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
  1. 生成 RSA公钥 rsa_public_key_java.pem,PKCS8 对应的公钥
openssl rsa -in rsa_private_key_java.pem -pubout -out rsa_public_key_java.pem
  1. 从公钥 rsa_public_key.pem 获取十六进制的公钥(第一段16进制字符串)
openssl asn1parse -out temp.ans -i -inform PEM<rsa_private_key.pem
  1. 从公钥 rsa_public_key.pem 获取十六进制的公钥(第一段16进制字符串) PKCS8 对应的十六进制的公钥
openssl asn1parse -out temp_java.ans -i -inform PEM<rsa_private_key_java.pem

生成签名

// 私钥路径
$rsaPrivateKeyPath = '/home/rsa_private_key.pem';
// 获取私钥内容
$privateKey = opensll_get_privatekey($rsaPrivateKeyPath);
// 注意这里可以不通过函数获取文件内家的方式获取私钥,也可以直接把文件内的字符串原样赋值给$privateKey
// 待签名字符串
$data = 'id=1&name=xiaoming';
// 进行签名
openssl_sign($data, $sign, $privateKey);
// 为了防止乱码对签名结果进行base64转码
$sign = base64_encode($sign);

校验签名

// 公钥路径
$rsaPublicKeyPath = '/home/rsa_public_key.pem';
// 获取公钥内容
$publicKey = openssl_get_publickey($rsaPublicKeyPath);
// 待校验的签名字符串
$data = 'id=1&name=xiaoming';
// 进行校验
// 已知签名字符串
$sing = '1341rqeqrrweq';
// 因为我这上面是进行了base64转码的,所以这里要先解码
$result = openssl_verify(base64_decode($data), $sign, $publicKey);

2.ras双向加密

相关函数

openssl_public_encrypt() 公钥加密

opensll_public_decrypt() 公钥解密

openssl_private_encrypt() 私钥加密

openssl_private_decrypt() 私钥解密

公钥加密与私钥解密

加密

// 公钥路径
$rsaPublicKeyPath = '/home/rsa_public_key.pem';
// 获取公钥内容
$publicKey = openssl_get_publickey($rsaPublicKeyPath);
// 待校验的签名字符串
$data = 'id=1&name=xiaoming';
// 进行加密
openssl_public_encrypt($data, $encryptData, $publicKey);
// 防止乱码进行base64转码,解密时也要先base64_decode
$result = base64_encode($encryptData);

解密

// 公钥路径
$rsaPublicKeyPath = '/home/rsa_public_key.pem';
// 获取公钥内容
$publicKey = openssl_get_publickey($rsaPublicKeyPath);
// 已加密的字符串
$data = 'afafadfasd';
// 进行加密
openssl_public_decrypt(base64_decode($data), $decryptData, $publicKey);
// 加密结果
$result = $decryptData;

js rsa加密与解密

注意js中传的公钥或私钥都是不带-----的开头的字符串,而且没有换行。

<script src="http://passport.cnblogs.com/scripts/jsencrypt.min.js"></script>
<script>
	function encrypt(str) {
		var encrypt = new JSEncrypt();
	    encrypt.setPublicKey('ttxseokm4vQTWukPqEthBWSdqlC/+6FM74z2Oi506y+LSRNcMijeUEm2hYRM9x2+zh0cvVA2iCM71KaxcFlzUl9tUxBAPr7S0hOwCQIDAQAB');
	    var data = encrypt.encrypt(str);
	    return data;
	}

	function decrypt(encrypted) {
		var decrypt = new JSEncrypt();
        decrypt.setPrivateKey('1111adfasdasdaf');
        var uncrypted = decrypt.decrypt(encrypted);
        return uncrypted;
	}
</script>

说明:公钥加密的数据需要使用私钥进行解密,同理,私钥加密的数据需要使用公钥才能进行解密。
私钥进行加密与解密的用法与公钥一样,不再举例。

3.DES双向加密

相关函数

openssl_get_cipher_methods() 可用的加密算法列表

扫描二维码关注公众号,回复: 6410802 查看本文章

openssl_cipher_iv_length() 获取指定算法的iv初始化向量的长度

openssl_random_pseudo_bytes($len) 随机获取一个指定长度的初始化向量

openssl_encrypt() 加密

openssl_decrypt() 解密

加密

加密所使用的函数为openssl_encrypt($data, $method, $key, $options, $iv),参数说明如下:

  • $data 待签名字符串
  • $method 所采用的加密算法,如des-ecb
  • $key 加密采用密钥
  • $options 可选, 填充方式,默认使用0即可,不同的语言之间如果出现解密不了的情况,一种是算法错误,另一种情况就是使用的填充方式不同
  • $iv 可选,初始化向量

特别说明:不同的加密算法对应着不同长度的初始化向量长度,指定的加密算法所需要的初始化向量长度可以使用函数openssl_cipher_iv_length($method)获取。有一些算法的初始化向量的长度为0,那么使用这些算法的时候,不需要传$iv这个参数,如des-ecb的初始化向量的长度为0,使用这种加密算法时不需要传$iv参数

下面以des-ecb算法为例:
js下载链接:``

/*加密*/
// 密钥
$key = 'adfafvadfa1e1';
// 待加密数据
$data = '1832587802';
// 加密方式
$method = 'des-ecb';
$result = openssl_encrypt($data, $method, $key);

/*解密*/
// 密钥
$key = 'adfafvadfa1e1';
// 待解密数据
$data = 'ma7oRNLDBkoHaPw5DcLRhg==';
// 加密方式
$method = 'des-ecb';

$result = openssl_decrypt($data, $method, $key);

js加密

以下是js示例代码与phpdes-ecb对应:
js下载链接http://note.youdao.com/noteshare?id=e6532e12c49730042740414b25bfeb5e&sub=861CE888ECD44DAFAD76EF7D1E61C815

<script src="./cryptojs/rollups/tripledes.js"></script>
<script src="./cryptojs/components/mode-ecb.js"></script>
<script>
// DES加密
function encryptByDES(message, key) {
    var keyHex = CryptoJS.enc.Utf8.parse(key);
    var encrypted = CryptoJS.DES.encrypt(message, keyHex, {
        mode: CryptoJS.mode.ECB,
        padding: CryptoJS.pad.Pkcs7
    });
    return encrypted.toString();
}
//DES 解密
function decryptByDES(ciphertext, key) {
    var keyHex = CryptoJS.enc.Utf8.parse(key);
    // direct decrypt ciphertext
    var decrypted = CryptoJS.DES.decrypt({
        ciphertext: CryptoJS.enc.Base64.parse(ciphertext)
    }, keyHex, {
            mode: CryptoJS.mode.ECB,
            padding: CryptoJS.pad.Pkcs7
            //这一步 是来填写 加密时候填充方式 padding: CryptoJS.pad.Pkcs7
        });
    return decrypted.toString(CryptoJS.enc.Utf8);
}
</script>

猜你喜欢

转载自blog.csdn.net/weixin_37825371/article/details/90665543