V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
banksiae
V2EX  ›  程序员

python rsa 签名方法

  •  
  •   banksiae · 2016-09-07 14:56:11 +08:00 · 4381 次点击
    这是一个创建于 2997 天前的主题,其中的信息可能已经有所发展或是发生改变。

    要在 python 中利用已知的 privateKey 做签名,没搞定~~

    下面一堆代码开始呈现~~

    java 的代码:

        public static final String KEY_ALGORITHM = "RSA";
    public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
    
    private static final String PUBLIC_KEY = "RSAPublicKey";
    private static final String PRIVATE_KEY = "RSAPrivateKey";
    
        public static String sign(byte[] data, String privateKey) throws Exception {
    	// 解密由 base64 编码的私钥
    	byte[] keyBytes = decryptBASE64(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 encryptBASE64(signature.sign());
    }
    
        public static boolean verify(byte[] data, String publicKey, String sign)
    		throws Exception {
    
    	// 解密由 base64 编码的公钥
    	byte[] keyBytes = decryptBASE64(publicKey);
    
    	// 构造 X509EncodedKeySpec 对象
    	X509EncodedKeySpec keySpec = new X509EncodedKeySpec(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(decryptBASE64(sign));
    }
    
        public static void main(String[] args) throws Exception {
    	String s = "wxt1987";
    	String pubKey ="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCJ7cCT/g3+ACVX9ZHlFGWaLgF2yShMP1TN+A2g2S6pa8oDJSa/b6ixy8Gx0VNOnUHDwZybHmn8OHa0BXhifoZUYmL7NzqhoeIkoid7koNdx6bG7KeXHf1t+hndS3By2se+0Q/Fb1nKfzsBKoFTuqI5dVoysF3EUTEkUGsFno3PZwIDAQAB";
    	String pk = "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAMNSf6Ez8B7mm266zPhoVJo9C1k+5ywDjBWjKgD7yEsxMe4RZx2N0p7Bx/1sUfaSvC2mjoIbQIYUGP2K9/ycbN4Jzq3rx8zkidXSg7FS6NcFeFekS+8O70X5hp2e/qXHwzStpZHHy6EpSF3M8oRuJqIwk8iHgh0uDPE5iWyRiv0PAgMBAAECgYBx6hWBoNb0Tq5sIAoW/lIJOnz56dPNOaxjmiuPM0kXgXOLUx7+f45NBNtsk9YhpmaVgUQv4VD6YZJJnNkQvPJIb71joPYKVYiGUkzFPrUdmUtSPkuWcaGvx3TefmPibL9TjUAY3408Om6YO54oFIWt5y/sMrsdiFRa9Lu5bREwsQJBAO39sZ2aDQqPRieSPHwnyDHlunpSmQ2XzmjtssoTmwo6rAmG/q6lWp5SX4GZ06rW9BKl2Z0VA0ImzdmF+83lflMCQQDSGjxp3oiZI56BHYfIlFCs9f9omUW8KrQXUv5XJVw1Ba9qv8mpAJURrFdAfljYHa+BFWMMuRrqnR/fHjrzE1bVAkEA37g3SmbxUXbjxPkkILYo7Db/eFPDCtMktuCTzIBno1MKPB6JtVU9fU0D+MnI/3T3lbwQeCizmnDt20inL6NHfwJBAKRe8jTBbIyiWTcaK0i5AATQz+i9QNldb1dwDpuPFvxEXmBdex9E3VreQcSrFEa/sraCTON/TZePJYgg1m2lC6ECQQCuAZ8CRsDrEAGyFgVJRDfmoOfPZHHmKgb2OZXVpssPBT17vO3iP0VATbiaZ7yYymcppgBdL6ktcVChYTaCeojA";
    	String sign = RSACoder.sign(s.getBytes(), pk);
    
    	System.out.println(sign);
                //签名结果
                // sign = "II9OcjgKQZlJ1N7R+8qYU6IE098dBd+ABEIGpREXo6jVaM9+FpJA6cdZreyCJlMg5hPjc4TtL2XD+UWRBMJ+D9CnwMDZhyDYEkg0ToUs667IbvI0w87CH2ElTjquTlhjdvEkStTHbWP7+k3YMa0DwNFWiG3BsXnK45ptiKCRxv4="
    
    	String m = "wxt1987";
    	boolean ok = RSACoder.verify(m.getBytes(), pubKey, sign);
    	System.out.println(ok);
    

    python 用 pycrypto 做签名:

        from Crypto.PublicKey import RSA
        from Crypto.Signature import PKCS1_v1_5
        from Crypto.Hash import SHA
        from base64 import b64decode
    
        pk= 'MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAMNSf6Ez8B7mm266zPhoVJo9C1k+5ywDjBWjKgD7yEsxMe4RZx2N0p7Bx/1sUfaSvC2mjoIbQIYUGP2K9/ycbN4Jzq3rx8zkidXSg7FS6NcFeFekS+8O70X5hp2e/qXHwzStpZHHy6EpSF3M8oRuJqIwk8iHgh0uDPE5iWyRiv0PAgMBAAECgYBx6hWBoNb0Tq5sIAoW/lIJOnz56dPNOaxjmiuPM0kXgXOLUx7+f45NBNtsk9YhpmaVgUQv4VD6YZJJnNkQvPJIb71joPYKVYiGUkzFPrUdmUtSPkuWcaGvx3TefmPibL9TjUAY3408Om6YO54oFIWt5y/sMrsdiFRa9Lu5bREwsQJBAO39sZ2aDQqPRieSPHwnyDHlunpSmQ2XzmjtssoTmwo6rAmG/q6lWp5SX4GZ06rW9BKl2Z0VA0ImzdmF+83lflMCQQDSGjxp3oiZI56BHYfIlFCs9f9omUW8KrQXUv5XJVw1Ba9qv8mpAJURrFdAfljYHa+BFWMMuRrqnR/fHjrzE1bVAkEA37g3SmbxUXbjxPkkILYo7Db/eFPDCtMktuCTzIBno1MKPB6JtVU9fU0D+MnI/3T3lbwQeCizmnDt20inL6NHfwJBAKRe8jTBbIyiWTcaK0i5AATQz+i9QNldb1dwDpuPFvxEXmBdex9E3VreQcSrFEa/sraCTON/TZePJYgg1m2lC6ECQQCuAZ8CRsDrEAGyFgVJRDfmoOfPZHHmKgb2OZXVpssPBT17vO3iP0VATbiaZ7yYymcppgBdL6ktcVChYTaCeojA'
    
        keyDER = b64decode(pk)
        rsakey = RSA.importKey(keyDER)
        signer = PKCS1_v1_5.new(rsakey) 
        data = "wxt1987"
        h = SHA.new(data)
        signature = signer.sign(h)
        
        
        #签名结果
        #signature = "wcS/9xJbHun4cY5p9WXMqINcJz6QVXYOI80fYbY1h06OP2tJke8bftT7eG1ZVAn4DrNkTMWhwNldXWg9PuTpjcvJu+I/A/YatMLybyCywAzPCYWO5pgzv3WzhP9ahY0h8B4NB9v+qLsslxQcsRbMM/winyouH9q73mmQh064nVU="
    

    python 的签名错了,求赐予我愚笨的脑袋一些灵光

    3 条回复    2016-09-07 15:53:05 +08:00
    kinghui
        1
    kinghui  
       2016-09-07 15:33:28 +08:00
    摘要算法 Java 用的 MD5, Python 用的 SHA.
    kinghui
        2
    kinghui  
       2016-09-07 15:34:03 +08:00
    banksiae
        3
    banksiae  
    OP
       2016-09-07 15:53:05 +08:00
    @kinghui 十分感谢
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1004 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 19:54 · PVG 03:54 · LAX 11:54 · JFK 14:54
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.