2017-08-08 3 views
1

Ich muss ein Passwort verschlüsseln und es als HTTP-Header hinzufügen, um einen Rest-Aufruf von einem Python-Client zu machen. Ich versuche, den folgenden C# -Code zu implementieren, der unten in Python aufgeführt ist, aber die restliche POST-Anfrage scheint mit Python zu versagen, da die verschlüsselte Passwort-Zeichenkette von Python nicht mit dem verschlüsselten Passwort von C# übereinstimmt. Der C# Code erzeugt das korrekte verschlüsselte PasswortRSA Passwort mit einem öffentlichen Modul und Exponent in Python verschlüsseln

Modul: "w1jcEfmxCTz5aB9wGg1Vl5K45VUm8Aj7+05sBarmrwbvC9BNjAqSySPmC2ajWSQGdmBs4xylKZjHKaXg5rxuNw=="

Exponent:

"AQAB" 

Passwort zu verschlüsseln: 'tricky'

verschlüsselte Passwort von C# (behält jedes Mal ändert es erzeugt wird) : '%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'

verschlüsseltes Kennwort von 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'

Hier ist mein Python-Code PyCrypto verwenden, die die Verschlüsselung funktioniert:

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 

Dies ist der C# -Code, der die Verschlüsselung funktioniert:

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

Alle Ideen, was könnte ich falsch sein mit dem Verschlüsseln des Passwortes mit RSA in Python?

+2

Warum nicht einfach HTTPS verwenden, das alles verschlüsselt. – zaph

+0

'byteorder = sys.byteorder' ist falsch, es sollte einfach' byteorder = 'big'' sein. –

+2

Sie wissen noch nicht, ob Sie das Richtige tun. Sie müssen in der einen Sprache verschlüsseln und in der anderen entschlüsseln, um die Kompatibilität zu überprüfen, da RSA randomisiert Padding hat. Wie auch immer, benutze einfach HTTPS mit einem gültigen Serverzertifikat. Dafür ist Let's encrypt. –

Antwort

0

Um dem C# -Code zu entsprechen, müssen Sie den Big-Endian-Modulus und -Ponten korrekt analysieren und PKCS v1.5-Padding verwenden. In diesem Beispiel wird der Code geringfügig geändert, um dies anzuzeigen.

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

Super! Das hat den Trick gemacht. Ich hatte vorher PKCS1_v1_5 versucht, hatte aber die falsche Byte-Reihenfolge. Es funktioniert jetzt. Vielen Dank! –

+0

@rohitramesh: Bitte akzeptieren Sie die Antwort dann. Vielen Dank. –

Verwandte Themen