0

Here is the code, the second (message, signature and public key) works fine on Java, can verify the message. But when I am using python, it will failed. If am signed the message and the code will verify the message correctly. Would some one help me to check the problem? Thank you.

# -*- 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)
boykimi
  • 1
  • 1

3 Answers3

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)
Waket Zheng
  • 5,065
  • 2
  • 17
  • 30
0

Below is the java code, it works fine with the same signature and public key.

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));
}

}

boykimi
  • 1
  • 1
  • You have posted multiple answers. Stackoverflow is not a forum. Please combine your "answers" into one and delete the other. – Robert Mar 10 '19 at 15:42
0

Finally, I get the answer. In java

DigestUtils.sha256(data) did hash, SHA256WithRSA algorithm will do hash

So what I should do is hash 2 times in my python code

boykimi
  • 1
  • 1
  • You have posted multiple answers. Stackoverflow is not a forum. Please combine your "answers" into one and delete the other. – Robert Mar 10 '19 at 15:42