签名使用的hash算法为SHA256,填充规则用RSA-PSS
首先使用composer安装phpseclib/phpseclib指定版本1.0.19:
composer require phpseclib/phpseclib 1.0.19
php部分签名和验签
/**
* 根据原文生成签名内容
*
* @param array $data 原文内容
* @return string
*/
public function sign($data = [])
{
$rsa = new Crypt_RSA();
$rsa->loadKey($this->private_key);
$rsa->setHash('sha256');
$rsa->setMGFHash('sha256');
$rsa->setSaltLength(32); // CRYPT_RSA_SIGNATURE_PSS 需要设置 Salt 长度为32
//设置签名模式 CRYPT_RSA_SIGNATURE_PKCS1 CRYPT_RSA_SIGNATURE_PSS
$rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PSS);
$encrypted = $rsa->sign($data);
//$encrypted = pack("H*",$encrypted);
//$encrypted = bin2hex($encrypted);
$signature = base64_encode($encrypted);
return $signature;
}
/**
* 验证签名是否正确
*
* @param string $data 签名的原文
* @param string $signature 签名
*
* @return bool
*/
function verifySign($data = '', $signature = '')
{
$rsa = new Crypt_RSA();
$rsa->loadKey($this->public_key);
$rsa->setHash('sha256');
$rsa->setMGFHash('sha256');
$rsa->setSaltLength(32);
//设置签名模式 CRYPT_RSA_SIGNATURE_PKCS1 CRYPT_RSA_SIGNATURE_PSS
$rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PSS);
$signature = base64_decode($signature);
return $rsa->verify($data, $signature);
}
python部分rsa签名与验签
import Crypto.PublicKey.RSA as RSA
import Crypto.Random
import Crypto.Hash.SHA256 as SHA256
from Crypto.Signature import PKCS1_PSS
from Crypto.Signature import PKCS1_v1_5
import base64
import json
PRIVATE_KEY = '-----BEGIN PRIVATE KEY-----\n' \
'\n' \
'-----END PRIVATE KEY-----'
PUBLIC_KEY = '-----BEGIN PUBLIC KEY-----\n' \
'\n' \
'-----END PUBLIC KEY-----'
# 签名
def sign(message, private_key):
key = RSA.importKey(private_key)
sha256 = SHA256.new()
sha256.update(message)
signer = PKCS1_PSS.new(key)
# signer = PKCS1_v1_5.new(key)
signature = signer.sign(sha256)
return base64.b64encode(signature)
data = 'test'
# 字符串encode将获得一个bytes对象
data = str.encode(data)
a = sign(data, PRIVATE_KEY)
a = bytes.decode(a)
print(a)
# 验签
def verify(message, signature, public_key):
signs = base64.b64decode(signature)
key = RSA.importKey(public_key)
sha256 = SHA256.new()
sha256.update(message)
verifier = PKCS1_PSS.new(key)
return verifier.verify(sha256, signs)
b = verify(data, a, PUBLIC_KEY)
print(b)