2017-08-08 55 views
1

我需要加密密码并将其添加为http标头,以便从python客户端进行其他调用。我试图在Python中实现下面列出的C#代码,但其余的POST请求似乎与Python失败,因为从python生成的加密密码字符串似乎没有匹配来自C#的加密密码。 C#代码生成正确的加密的密码RSA使用Python中的公共模和指数对密码进行加密

模量:"w1jcEfmxCTz5aB9wGg1Vl5K45VUm8Aj7+05sBarmrwbvC9BNjAqSySPmC2ajWSQGdmBs4xylKZjHKaXg5rxuNw=="

指数:

"AQAB" 

密码来加密:'tricky'

从C#(它是产生的每个时间不断变化)

加密的密码:'%14%1d%0a%bb%a0X%24H%ad%ce%9aG%f6a%dau%d8%01%ec%d5)+%d3%11%8e%3ew%c8K%dce%ec%84K%e6%1d%ea%81%3e%d14%87%80s%8eo%a6%bc%fd%1b%8f%a1V8%c8%96%b1%ec%1f%d7qd%bbz'

Python加密的密码:'%21%F6%7E.i%F4%F4%5E%E5%A9v%03E%8C%1C%3E%F1%D7%DBT%A2%03z%BF%E2%E8%8FJh%E3%85%AA%24%25%C2%C9Hg%18z%22a%F8g%0B%81%3C%DC%FEr%F8C%98s%B5%DA1%F6%60%23%BAw%10F'

下面是使用Pycrypto我的Python代码做加密:

from base64 import b64decode 
from Crypto.PublicKey.RSA import construct 

def get_encrypted_password(password, modulus, exponent): 
    password = password.encode('utf-8') 

    # decode base64 string to be used as modulus(n) and exponent(e) components for constructing the RSA public key object 
    modulus = b64decode(modulus) 
    exponent = b64decode(exponent) 

    n = int.from_bytes(modulus, byteorder=sys.byteorder) 
    e = int.from_bytes(exponent, byteorder=sys.byteorder) 

    pubkey = construct((n,e)) 
    encrypted = pubkey.encrypt(password,None)[0] 
    #url encode the encrypted password 
    encrypted = urllib.parse.quote_plus(encrypted) 
    return encrypted 

这是C#代码做加密:对我可能是做错了

public static string EncryptForTransport(string strToEncrypt, string rsaPublicKey) 
     { 
      KeyContainerPermission permission = new KeyContainerPermission(KeyContainerPermissionFlags.AllFlags); 

      permission.Assert(); 

      if (string.IsNullOrEmpty(strToEncrypt)) 
      { return strToEncrypt; } 

      RSACryptoServiceProvider rsaEncryptor = GetRsaEncryptor(rsaPublicKey); 

      byte[] buffer = rsaEncryptor.Encrypt(Encoding.UTF8.GetBytes(strToEncrypt), false); 

      try 
      { 
       rsaEncryptor.Clear(); 
      } 
      catch (CryptographicException) 
      { 
       //errors may occur ignore them. 
      } 

      string encryptedStr = HttpUtility.UrlEncode(buffer);// byteConverterGetString; 

      return encryptedStr; 

     } 

     private static RSACryptoServiceProvider GetRsaEncryptor(string rsaPublicKey) 
     { 
      RSACryptoServiceProvider.UseMachineKeyStore = true; 
      RSACryptoServiceProvider rsaEncryptor = RSACryptoServiceProvider.Create() as RSACryptoServiceProvider; 
      if (rsaEncryptor.PersistKeyInCsp) 
       rsaEncryptor.PersistKeyInCsp = false; 
      rsaEncryptor.FromXmlString(rsaPublicKey); 

      return rsaEncryptor; 
     } 

任何想法在Python中使用RSA加密密码?

+2

为什么不使用HTTPS,它将加密所有内容。 – zaph

+0

'byteorder = sys.byteorder'是错误的,它应该只是'byteorder ='big'' –

+2

你还不知道你是否做了正确的事情。您需要使用一种语言进行加密并在另一种语言中解密以检查兼容性,因为RSA已经随机填充了。无论如何,只需使用具有有效服务器证书的HTTPS即可。这就是我们加密的目的。 –

回答

0

为了匹配C#代码的功能,您必须正确解析big-endian模数和指数,并使用PKCS v1.5填充。下面的这个例子稍微修改你的代码来显示这个。

from base64 import b64decode 
from Crypto.PublicKey.RSA import construct 
from Crypto.Cipher import PKCS1_v1_5 
import urllib.parse 


def get_encrypted_password(password, modulus, exponent): 
    password = password.encode('utf-8') 

    # decode base64 string to be used as modulus(n) and exponent(e) components for 
    # constructing the RSA public key object 

    modulus = b64decode(modulus) 
    exponent = b64decode(exponent) 

    n = int.from_bytes(modulus, byteorder='big') 
    e = int.from_bytes(exponent, byteorder='big') 

    pubkey = construct((n, e)) 
    pubkey = PKCS1_v1_5.new(pubkey) 
    encrypted = pubkey.encrypt(password) 
    # url encode the encrypted password 
    encrypted = urllib.parse.quote_plus(encrypted) 
    return encrypted 
+0

太棒了!那就是诀窍。我曾尝试过PKCS1_v1_5,但字节顺序错误。它现在有效。谢谢! –

+0

@rohitramesh:请接受答案。谢谢。 –

相关问题