Python与Java之间的签名和验签问题

xiaoxiao2025-08-14  32

// 最新碰到一个需求, 需要同java下的签名做验签, 感觉有必要总结下: // 整个过程碰到以下几个问题: /* 1、如何生成指定的公私钥? # 使用linux指令openssl, openssl这个东西是真的强, (证书问题, 加解密问题, 公私钥问题等)都能帮你处理的妥妥滴; 有兴趣和时间的童鞋建议好好玩玩这东西. (yum install openssl* -y) 私钥: openssl genrsa -out rsa_private_key.pem 1024 // 不指定, 默认为2048位字符 公钥: openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem 2、如何验证公私钥是匹配的?(私钥签的名,公钥可以验签通过,那么就是匹配的) # 同样使用openssl, 姿势如下: 签名: openssl dgst -sign rsa_private.key -sha1 -out sha1_rsa_file.sign file.txt 验签: openssl dgst -verify rsa_public.key -sha1 -signature sha1_rsa_file.sign file.txt 原文链接: https://blog.csdn.net/scuyxi/article/details/55002130 # http://tool.chacuo.net/cryptrsakeyvalid // 这个网址也可以, 效果不是很好 3、pkcs1与pkcs8格式转换的问题? # 本处摘自 https://blog.csdn.net/six66hao/article/details/81814576 常用的rsa密钥有两种格式,一种为pkcs1,首尾分别为: # 公钥 -----BEGIN RSA PUBLIC KEY----- -----END RSA PUBLIC KEY----- # 私钥 -----BEGIN RSA PRIVATE KEY----- -----END RSA PRIVATE KEY----- 另一种为pkcs8,首位分别为: # 公钥 -----BEGIN PUBLIC KEY----- -----END PUBLIC KEY----- # 私钥 -----BEGIN PRIVATE KEY----- -----END PRIVATE KEY----- 使用python rsa模块生成的公/私钥均为pkcs1格式,生成密钥对代码如下: (public_key, private_key) = rsa.newkeys(lens) with open('public.pem', 'wb') as f: f.write(public_key.save_pkcs1()) with open('private.pem', 'wb') as f: f.write(private_key.save_pkcs1()) 4、不同语言之间做签名与验签时的对应问题? # 找出对应的库/包 # 采用相同的编码格式, 加解密算法 # 公私钥必须是配对的 5、老掉牙的字符编码格式问题, 还是不熟练 # py3 bytes object mybyte = b"test" # str object mystr = "test" # str to bytes bytes(mystr, encoding="utf8") # bytes to str str(mybyte, encoding="utf-8") # py2 str 转 utf8 str.encode(mystr, 'utf-8') */ // 说了碰到的问题, 自然要玩玩签名与验签 package myJava; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.spec.PKCS8EncodedKeySpec; import java.util.Base64; import java.security.Signature; import java.security.PublicKey; import java.security.spec.X509EncodedKeySpec; public class verifySignature { public static final String KEY_ALGORITHM = "RSA"; public static final String SIGNATURE_ALGORITHM = "SHA256WithRSA"; public static String sign(byte[] data, String privateKey) throws Exception { // 解密由 base64 编码的私钥 final Base64.Encoder encoder = Base64.getEncoder(); final Base64.Decoder decoder = Base64.getDecoder(); byte[] keyBytes = decoder.decode(privateKey); // 构造 PKCS8EncodedKeySpec 对象 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); // KEY_ALGORITHM 指定的加密算法 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 取私钥对象 PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec); // 用私钥对信息生成数字签名 Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initSign(priKey); signature.update(data); return encoder.encodeToString(signature.sign()); } public static boolean verify(byte[] data, String publicKey, String sign) throws Exception { // 解码由 base64 编码的公钥 final Base64.Decoder decoder = Base64.getDecoder(); final byte[] keyBytes = publicKey.getBytes("UTF-8"); // 构造 X509EncodedKeySpec 对象 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decoder.decode(keyBytes)); // KEY_ALGORITHM 指定的加密算法 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)); } public static void main(String[] args) throws Exception { String s = "hello world"; String pubKey = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALyJy3rlD9EtWqVBzSIYxRRuFWRVn3juht2nupDCBSsWi7uKaRu3W0gn5y6aCacArtCkrf0EehwYRm0A4iHf8rkCAwEAAQ=="; // PKCS8格式私钥(可由PKCS1格式转换) String priKey = "MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAvInLeuUP0S1apUHNIhjFFG4VZFWfeO6G3ae6kMIFKxaLu4ppG7dbSCfnLpoJpwCu0KSt/QR6HBhGbQDiId/yuQIDAQABAkEAqm/y15UtOE7Ey/HxLCqyNqbRhdN1h5AxsT0IhgYvP+PhWGc3hRElMwNCdiNaJBh04R1iK6wmKoi3DSjkdU6IAQIhAPRL9khAdPMxjy5tpswNWeaDjNJrlUKEnItQUkoHqve5AiEAxZIDz235HcUgLg9ApYK4spOpzLDGCCgfO3FxmrUEUwECIEaLjQIOQvdbT1p75Ze1H0nWoRq+YGrF+qKsPicMkc1ZAiARlNTR+K9afthGQQU3tVJKUemiVXjJ8QgWehnp8oHYAQIhANsC2fEVjWv94Oy2c8I9qhuX+yfNtvZ2m+Kmf2o4JFrR"; String sign = "cPz4BuUiKXDDBXjTx5VcMFgDFdCKVfn50Idv7pYhmiivrmx94zk0Fpk6IbKjReiqaNfRhEqGCIVpdFNiKLVKfA=="; String m = "hello world"; String after_sign = sign(s.getBytes(), priKey); System.out.println(after_sign); boolean ok = verify(m.getBytes(), pubKey, sign); System.out.println(ok); } } /* 输出结果: cPz4BuUiKXDDBXjTx5VcMFgDFdCKVfn50Idv7pYhmiivrmx94zk0Fpk6IbKjReiqaNfRhEqGCIVpdFNiKLVKfA== true */ # -*- 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 origin_data = 'hello world' public_key = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALyJy3rlD9EtWqVBzSIYxRRuFWRVn3juht2nupDCBSsWi7uKaRu3W0gn5y6aCacArtCkrf0EehwYRm0A4iHf8rkCAwEAAQ==' signature = 'cPz4BuUiKXDDBXjTx5VcMFgDFdCKVfn50Idv7pYhmiivrmx94zk0Fpk6IbKjReiqaNfRhEqGCIVpdFNiKLVKfA==' private_key = 'MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAvInLeuUP0S1apUHNIhjFFG4VZFWfeO6G3ae6kMIFKxaLu4ppG7dbSCfnLpoJpwCu0KSt/QR6HBhGbQDiId/yuQIDAQABAkEAqm/y15UtOE7Ey/HxLCqyNqbRhdN1h5AxsT0IhgYvP+PhWGc3hRElMwNCdiNaJBh04R1iK6wmKoi3DSjkdU6IAQIhAPRL9khAdPMxjy5tpswNWeaDjNJrlUKEnItQUkoHqve5AiEAxZIDz235HcUgLg9ApYK4spOpzLDGCCgfO3FxmrUEUwECIEaLjQIOQvdbT1p75Ze1H0nWoRq+YGrF+qKsPicMkc1ZAiARlNTR+K9afthGQQU3tVJKUemiVXjJ8QgWehnp8oHYAQIhANsC2fEVjWv94Oy2c8I9qhuX+yfNtvZ2m+Kmf2o4JFrR' 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(origin_data, encoding="utf-8")) signer = PKCS1_v1_5.new(key) signature = signer.sign(hash_value) return b64encode(signature) def verify(): key_bytes = bytes(public_key, encoding="utf-8") key_bytes = b64decode(key_bytes) key = RSA.importKey(key_bytes) hash_value = SHA256.new(bytes(origin_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.") if __name__ == '__main__': print(sign()) verify() ''' 输出结果: b'cPz4BuUiKXDDBXjTx5VcMFgDFdCKVfn50Idv7pYhmiivrmx94zk0Fpk6IbKjReiqaNfRhEqGCIVpdFNiKLVKfA==' The signature is authentic. '''

 

转载请注明原文地址: https://www.6miu.com/read-5034818.html

最新回复(0)