2017-02-05 4 views
-1

私は現在、暗号化と解読のためにpython暗号化ライブラリとRSAを使用しています。RSAの長さは鍵のサイズと同じでなければなりませんエラー

raise ValueError("Ciphertext length must be equal to key size.") 

私の暗号化と復号化のコードは次のようになります:

class AppCryptography(): 

    def generate_rsa_keypair(self, bits=4096): 
     return rsa.generate_private_key(
      public_exponent=65537, 
      key_size=bits, 
      backend=default_backend() 
     ) 

    def load_private_key(self, pem_file_path): 

     with open(pem_file_path, "rb") as key_file: 
      private_key = serialization.load_pem_private_key(
       key_file.read(), 
       password=None, 
       backend=default_backend() 
      ) 

     return private_key 

    def load_public_key(self, pem_file_path): 

     with open(pem_file_path, "rb") as key_file: 
      public_key = serialization.load_pem_public_key(
       key_file.read(), 
       backend=default_backend() 
      ) 

     return public_key 

    def encrypt_password(self, public_key, password): 
     password = bytes(password) if not isinstance(password, bytes) else password 
     public_key = public_key if isinstance(public_key, RSAPublicKey) else self.load_pem_public_key(
      public_key_pem_export=public_key 
     ) 

     cipher_pass = public_key.encrypt(
      password, 
      padding.OAEP(
       mgf=padding.MGF1(algorithm=hashes.SHA1()), 
       algorithm=hashes.SHA1(), 
       label=None 
      ) 
     ) 

     return str(base64.b64encode(cipher_pass)) 

    def decrypt(self, private_key, cipher_pass): 
     cipher_pass = base64.b64decode(cipher_pass) if not isinstance(cipher_pass, bytes) else cipher_pass 
     private_key = private_key if isinstance(private_key, RSAPrivateKey) else self.load_pem_private_key(
      private_key_pem_export=private_key 
     ) 

     plain_text_pass = private_key.decrypt(
      cipher_pass, 
      padding.OAEP(
       mgf=padding.MGF1(algorithm=hashes.SHA1()), 
       algorithm=hashes.SHA1(), 
       label=None 
      ) 
     ) 
     return str(plain_text_pass) 
鍵の生成は、暗号化は動作しますが、それは、パスワードを解読することになると、私はこのトレースバックエラーメッセージに直面しています、正常に動作します私はこのスクリプトを実行すると

、エラーが発生したエラーが復号化機能から来ているが、私はエラーがfunctioにある場所を確認することができませんでしだ

crypter = AppCryptography() 

backend_public_key = crypter.load_public_key(dir_path + "/util/keys/backend_public_key.pem") 
frontend_private_key = crypter.load_private_key(dir_path + "/util/keys/frontend_private_key.pem") 

encrypted_password = crypter.encrypt_password(backend_public_key, password) 

signature = crypter.sign_data(frontend_private_key, password) 

backend_private_key = crypter.load_private_key(dir_path + "/util/keys/backend_private_key.pem") 
cleartext = crypter.decrypt(backend_private_key, encrypted_password) 

私のスタックトレースショーn定義。あなたのコード内の問題のようです何

File "/Users/Me/anaconda/envs/flask_dream/lib/python2.7/site-packages/sqlalchemy/orm/state.py", line 411, in _initialize_instance 
    return manager.original_init(*mixed[1:], **kwargs) 
File "/Users/Me/anaconda/envs/flask_dream/lib/python2.7/site-packages/sqlalchemy/ext/declarative/base.py", line 650, in _declarative_constructor 
    setattr(self, k, kwargs[k]) 
File "/Users/Me/Desktop/Projects/Flask-Dream/project_app/models.py", line 114, in password 
    cleartext = crypter.decrypt(backend_private_key, encrypted_password) 
File "/Users/Me/Desktop/Projects/Flask-Dream/project_app/util/crypto.py", line 121, in decrypt 
    label=None 
File "/Users/Me/anaconda/envs/flask_dream/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/rsa.py", line 397, in decrypt 
    raise ValueError("Ciphertext length must be equal to key size.") 
+0

非常に安全でない可能性がある使用法に応じて暗号化パスワードを使用するのはなぜですか。 – zaph

+0

私の暗号化されたサービスパスワードではありません(これはハッシュ+ソルトを使用しています)。個人アカウントでユーザーが入力したデータを暗号化する別の使用例です。私は非常に特定のアーキテクチャを持っています。 – mandok

+0

注:ハッシュ関数を使用するだけでは不十分で、単に塩を追加するだけでセキュリティを向上させることはほとんどありません。代わりに、約100msの間、ランダムな塩でHMACを繰り返し、塩をハッシュで保存します。 'PBKDF2'(別名' Rfc2898DeriveBytes')、 'password_hash' /' password_verify'、 'Bcrypt'などの関数を使用してください。要点は、攻撃者が無差別にパスワードを見つけるのに多くの時間を費やすことです。ユーザーを保護することが重要です。安全なパスワード方法を使用してください。 – zaph

答えて

2

は次の行です:今

cipher_pass = base64.b64decode(cipher_pass) if not isinstance(cipher_pass, bytes) else cipher_pass 

- 私は、Pythonを理解している場合、正しく - 文字列がこれは間違いである(特定のエンコーディングでバイトに格納されていますPython 2では大文字小文字の区別があり、strが使用されている場合はPython 3の場合もあります)。

これは、base64文字列がでものバイト文字列であり、isinstance(cipher_pass, bytes)がtrueを返すことを意味します。しかし、これはbase64のデコードがトリガされないことを意味します。つまり、暗号文が大きすぎて解読中に失敗することを意味します。

テキストインターフェイスが必要な場合は、常にbase64をデコードするのが最適です。

関連する問題