这是代码,第二个(消息,签名和公共密钥)在Java上可以正常工作,可以验证消息。但是当我使用python时,它将失败。 如果签名,则消息和代码将正确验证消息。 有人可以帮我检查一下问题吗?谢谢。
# -*- coding:utf-8 -*-
from Crypto.PublicKey import RSA
from Crypto.Hash import SHA256
from Crypto.Signature import PKCS1_v1_5
from base64 import b64decode, b64encode
public_key = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALyJy3rlD9EtWqVBzSIYxRRuFWRVn3juht2nupDCBSsWi7uKaRu3W0gn5y6aCacArtCkrf0EehwYRm0A4iHf8rkCAwEAAQ=='
private_key = 'MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAvInLeuUP0S1apUHNIhjFFG4VZFWfeO6G3ae6kMIFKxaLu4ppG7dbSCfnLpoJpwCu0KSt/QR6HBhGbQDiId/yuQIDAQABAkEAqm/y15UtOE7Ey/HxLCqyNqbRhdN1h5AxsT0IhgYvP+PhWGc3hRElMwNCdiNaJBh04R1iK6wmKoi3DSjkdU6IAQIhAPRL9khAdPMxjy5tpswNWeaDjNJrlUKEnItQUkoHqve5AiEAxZIDz235HcUgLg9ApYK4spOpzLDGCCgfO3FxmrUEUwECIEaLjQIOQvdbT1p75Ze1H0nWoRq+YGrF+qKsPicMkc1ZAiARlNTR+K9afthGQQU3tVJKUemiVXjJ8QgWehnp8oHYAQIhANsC2fEVjWv94Oy2c8I9qhuX+yfNtvZ2m+Kmf2o4JFrR'
bank_response_data = """{"head":{"vernbr":"1.0","mchnbr":"BILL0003","mchtyp":"BILLTYP","trscod":"BILL001","msgidc":"201805011230500001","sigtim":"20190307115511","sigalg":"SHA256WithRSA","retcod":"F","retmsg":"GWB2B006 源IP地址不在商户IP白名单中;商户编号:BILL0003;IP地址:123.139.40.150"}}"""
bank_response_signature = """uZl0/5D694GnAd/G9OPRs9BSd9fb0fZGXSGThBtgLnKi+CDQAdasOX05mKazXZki0blXxApGYRAWa/kOrf+Wl0USfklx0G5w/eGERfMdRWpvtV3S2MBCH/H/0T81nKGgn8svkT/Trj7+Mc+e654Jn8IijGyV9m8Ak92hG2bLtbc="""
bank_public_key = """MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDZs4l8Ez3F4MG0kF7RRSL+pn8MmxVE3nfdXzjx6d3rH8IfDbNvNRLS0X0b5iJnPyFO8sbbUo1Im4zX0M8XA0xnnviGyn5E6occiyUXJRgokphWb5BwaYdVhnLldctdimHoJTk3NFEQFav3guygR54i3tymrDc8lWtuG8EczVu8FwIDAQAB"""
def sign():
key_bytes = bytes(private_key, encoding="utf-8")
key_bytes = b64decode(key_bytes)
key = RSA.importKey(key_bytes)
hash_value = SHA256.new(bytes(bank_response_data, encoding="utf-8"))
signer = PKCS1_v1_5.new(key)
signature = signer.sign(hash_value)
return b64encode(signature)
def verify(data, signature, the_pub_key):
print(signature)
key_bytes = bytes(the_pub_key, encoding="utf-8")
key_bytes = b64decode(key_bytes)
key = RSA.importKey(key_bytes)
hash_value = SHA256.new(bytes(data, encoding="utf-8"))
verifier = PKCS1_v1_5.new(key)
if verifier.verify(hash_value, b64decode(signature)):
print("The signature is authentic.")
else:
print("The signature is not authentic.")
verify(bank_response_data, sign(), public_key)
verify(bank_response_data, bank_response_signature.encode('utf-8'),
bank_public_key)
答案 0 :(得分:0)
# -*- coding:utf-8 -*-
from Cryptodome.Signature import PKCS1_v1_5 # pip install pycryptodomex
from Cryptodome.Hash import SHA256
from Cryptodome.PublicKey import RSA
from base64 import decodebytes, encodebytes
public_key = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALyJy3rlD9EtWqVBzSIYxRRuFWRVn3juht2nupDCBSsWi7uKaRu3W0gn5y6aCacArtCkrf0EehwYRm0A4iHf8rkCAwEAAQ=="
private_key = "MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAvInLeuUP0S1apUHNIhjFFG4VZFWfeO6G3ae6kMIFKxaLu4ppG7dbSCfnLpoJpwCu0KSt/QR6HBhGbQDiId/yuQIDAQABAkEAqm/y15UtOE7Ey/HxLCqyNqbRhdN1h5AxsT0IhgYvP+PhWGc3hRElMwNCdiNaJBh04R1iK6wmKoi3DSjkdU6IAQIhAPRL9khAdPMxjy5tpswNWeaDjNJrlUKEnItQUkoHqve5AiEAxZIDz235HcUgLg9ApYK4spOpzLDGCCgfO3FxmrUEUwECIEaLjQIOQvdbT1p75Ze1H0nWoRq+YGrF+qKsPicMkc1ZAiARlNTR+K9afthGQQU3tVJKUemiVXjJ8QgWehnp8oHYAQIhANsC2fEVjWv94Oy2c8I9qhuX+yfNtvZ2m+Kmf2o4JFrR"
bank_response_data = """{"head":{"vernbr":"1.0","mchnbr":"BILL0003","mchtyp":"BILLTYP","trscod":"BILL001","msgidc":"201805011230500001","sigtim":"20190307115511","sigalg":"SHA256WithRSA","retcod":"F","retmsg":"GWB2B006 源IP地址不在商户IP白名单中;商户编号:BILL0003;IP地址:123.139.40.150"}}"""
bank_response_signature = """uZl0/5D694GnAd/G9OPRs9BSd9fb0fZGXSGThBtgLnKi+CDQAdasOX05mKazXZki0blXxApGYRAWa/kOrf+Wl0USfklx0G5w/eGERfMdRWpvtV3S2MBCH/H/0T81nKGgn8svkT/Trj7+Mc+e654Jn8IijGyV9m8Ak92hG2bLtbc="""
bank_public_key = """MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDZs4l8Ez3F4MG0kF7RRSL+pn8MmxVE3nfdXzjx6d3rH8IfDbNvNRLS0X0b5iJnPyFO8sbbUo1Im4zX0M8XA0xnnviGyn5E6occiyUXJRgokphWb5BwaYdVhnLldctdimHoJTk3NFEQFav3guygR54i3tymrDc8lWtuG8EczVu8FwIDAQAB"""
def sign(private_key=private_key, raw_string=bank_response_data):
private_key = RSA.importKey(decodebytes(private_key.encode()))
signer = PKCS1_v1_5.new(private_key)
signature = signer.sign(SHA256.new(raw_string.encode()))
return encodebytes(signature).decode().replace("\n", "")
def verify(data, signature, public_key):
print(signature)
key = RSA.importKey(decodebytes(public_key.encode()))
hash_value = SHA256.new(data.encode())
verifier = PKCS1_v1_5.new(key)
if verifier.verify(hash_value, decodebytes(signature.encode())):
print("The signature is authentic.")
else:
print("The signature is not authentic.")
verify(bank_response_data, sign(), public_key)
verify(bank_response_data, bank_response_signature, bank_public_key)
答案 1 :(得分:0)
下面是Java代码,使用相同的签名和公钥也可以正常工作。
import org.apache.commons.codec.digest.DigestUtils;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
public class MyTest {
public static final String KEY_ALGORITHM = "RSA";
public static final String SIGNATURE_ALGORITHM = "SHA256WithRSA";
public static void main(String[] args) {
String data = "{\"head\":{\"vernbr\":\"1.0\",\"mchnbr\":\"BILL0003\",\"mchtyp\":\"BILLTYP\",\"trscod\":\"BILL001\",\"msgidc\":\"201805011230500001\",\"sigtim\":\"20190307115511\",\"sigalg\":\"SHA256WithRSA\",\"retcod\":\"F\",\"retmsg\":\"GWB2B006 源IP地址不在商户IP白名单中;商户编号:BILL0003;IP地址:123.139.40.150\"}}";
String signature = "dnAFU2e5zFb8rJ1mXDNk5AG9UyujVIUArkBjb1Nonf7iMhZwHfHRO633eW5n7uELFnyJZk6Go2D6ovp4jEnIoA==";
String cmbcRespSignature = "uZl0/5D694GnAd/G9OPRs9BSd9fb0fZGXSGThBtgLnKi+CDQAdasOX05mKazXZki0blXxApGYRAWa/kOrf+Wl0USfklx0G5w/eGERfMdRWpvtV3S2MBCH/H/0T81nKGgn8svkT/Trj7+Mc+e654Jn8IijGyV9m8Ak92hG2bLtbc=";
String cmbcPublicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDZs4l8Ez3F4MG0kF7RRSL+pn8MmxVE3nfdXzjx6d3rH8IfDbNvNRLS0X0b5iJnPyFO8sbbUo1Im4zX0M8XA0xnnviGyn5E6occiyUXJRgokphWb5BwaYdVhnLldctdimHoJTk3NFEQFav3guygR54i3tymrDc8lWtuG8EczVu8FwIDAQAB";
try {
boolean verify = verify(DigestUtils.sha256(data), cmbcPublicKey, cmbcRespSignature);
if (verify) {
}
} catch (Exception e) {
}
}
public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {
final Base64.Decoder decoder = Base64.getDecoder();
final byte[] keyBytes = publicKey.getBytes("UTF-8");
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decoder.decode(keyBytes));
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PublicKey pubKey = keyFactory.generatePublic(keySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(pubKey);
signature.update(data);
return signature.verify(decoder.decode(sign));
}
}
答案 2 :(得分:0)
最后,我得到了答案。 在Java
中DigestUtils.sha256(data)进行了哈希处理, SHA256WithRSA算法将进行哈希处理
所以我应该做的是在我的python代码中哈希2次