【问题标题】:How to encrypt messages with ECC in pycryptodom如何在 pycryptodome 中使用 ECC 加密消息
【发布时间】:2018-05-26 02:13:39
【问题描述】:

我正在使用混合加密(RSA+AES),但长度很大,现在我想使用 ECC 而不是 RSA,但在 pycryptodom 中没有实现。 这是我的 RSA 代码

def generate_keys():
    key = RSA.generate(1024)
    private_key = key.exportKey(format='PEM', pkcs=8, 
                  protection="scryptAndAES128-CBC")
    f = open("private_key.pem", "wb")
    f.write(private_key)
    public_key = key.publickey().exportKey('PEM')
    f = open("public_key.pem", "wb")
    f.write(public_key)
    f.close()

def encrypt(username, msg):
    #get the reciever's public key
    f = open("{}.pem".format(username)) # a.salama.pem
    recipient_key = RSA.import_key(f.read())
    f.close()

    # Encrypt the session key with the reciever's public RSA key
    cipher_rsa = PKCS1_OAEP.new(recipient_key)

    # Encrypt the data with the AES session key
    session_key = get_random_bytes(16)

    cipher_aes = AES.new(session_key, AES.MODE_EAX)
    ciphertext, tag = cipher_aes.encrypt_and_digest(msg.encode('utf-
                    8'))
    encrypted_data = cipher_rsa.encrypt(session_key) + 
    cipher_aes.nonce + tag +  ciphertext    
    encrypted_data = base64.b64encode(encrypted_data)
    return encrypted_data

在尝试使用 ECC+AES 后,代码将是

from Crypto.PublicKey import ECC
from Crypto.Random import get_random_bytes
from Crypto.Cipher import AES, PKCS1_OAEP
import base64

def generate_keys():
    key = ECC.generate(curve='P-256') #3072 RSA 
    private_key = key.export_key(format='PEM')
    f = open('private_key.pem','wt')
    f.write(private_key)
    f.close()

    public_key = key.public_key().export_key(format='PEM')
    f = open('public_key.pem','wt')
    f.write(public_key)
    f.close()

def encrypt(username, msg):
    #get the reciever's public key
    f = open("{}.pem".format(username), 'rt') # a.salama.pem
    recipient_key = ECC.import_key(f.read())
    f.close()

    # Encrypt the session key with the reciever's public RSA key
    cipher_rsa = PKCS1_OAEP.new(recipient_key)

    # Encrypt the data with the AES session key
    session_key = get_random_bytes(16)
    #we use the EAX mode to allow detection of unauthorized 
    modifications.  
    cipher_aes = AES.new(session_key, AES.MODE_EAX)
    ciphertext, tag = cipher_aes.encrypt_and_digest(msg.encode('utf-
                      8'))
    encrypted_data = cipher_rsa.encrypt(session_key) + 
    cipher_aes.nonce + tag +  ciphertext    
    encrypted_data = base64.b64encode(encrypted_data)

    return encrypted_data.decode()

这给了我这一行的错误

cipher_rsa = PKCS1_OAEP.new(recipient_key)

但我想用公钥加密会话密钥,如何使用 pycryptodome 或任何其他方式进行加密

【问题讨论】:

  • 你能发布解决方案吗?如果你曾经找到它...
  • Pycryptodom 本身并没有为 ECC 编写代码,我认为它正在维护中。所以,很遗憾,我没有找到解决方案。

标签: python encryption pycrypto


【解决方案1】:

Pycryptodome 不支持基于椭圆曲线的加密(ECC 加密)。

改用 ECIES 算法,例如这个 Python 库:https://github.com/kigawas/eciespy

ECIES(椭圆曲线集成加密方案)是混合加密方案,它结合了 ECC 公钥加密 来对会话进行非对称加密密钥,稍后用于使用对称密码(例如使用 AES-GCM)加密输入数据。

【讨论】:

    【解决方案2】:

    我知道这是一个老问题,但对于其他来到这里的人来说:

    您现在可以为此使用 Pycryptodome 或 Cryptography。以 Pycrptodome 为例:

    from Crypto.PublicKey import ECC
    
    def get_or_create_public_key(filename: str = "private_key.pem"):
    """ Helper function to retrieve public key """
       private_key_file = os.path.join(settings.BASE_DIR, filename)
       if os.path.exists(private_key_file):
          file = open(private_key_file, "rt")
          private_key = ECC.import_key(file.read(), passphrase=settings.SECRET_KEY)
       else:
          private_key = ECC.generate(curve="P-256")
          file = open(private_key_file, "wt")
          file.write(
             private_key.export_key(
                format="PEM",
                use_pkcs8=True,
                passphrase=settings.SECRET_KEY,
                protection="PBKDF2WithHMAC-SHA1AndAES128-CBC",
            )
          )
          file.close()
       public_key = private_key.public_key()
       return public_key.export_key(format="PEM")
    

    【讨论】:

    • 这实际上没有帮助。问题是使用 ECC 密钥创建 PKCS1_OAEP 密码。目前导致“AttributeError:'EccKey'对象没有属性'n'”。
    猜你喜欢
    • 1970-01-01
    • 2021-09-04
    • 1970-01-01
    • 1970-01-01
    • 2015-08-07
    • 2016-02-08
    • 2020-05-07
    • 2022-01-16
    • 1970-01-01
    相关资源
    最近更新 更多