如何在pycryptodom中使用ECC加密消息

5

我正在使用混合加密(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或其他方式实现


你能否发布解决方案?如果你找到了的话... - elvainch
Pycryptodom本身没有为ECC编写代码,我认为它正在维护中。所以,不幸的是,我没有找到解决方案。 - Ahmed Salama
2个回答

4

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

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

ECIES(椭圆曲线综合加密方案)混合加密方案,它将ECC公钥密码学与非对称加密会话密钥相结合,用后者再使用对称密码(例如AES-GCM)加密输入数据。


1
此答案已过时,Pycryptodome现在支持ECC,请参见https://pycryptodome.readthedocs.io/en/latest/src/public_key/ecc.html。 - gdvalderrama

0
我知道这是一个老问题,但对于任何其他来到这里的人:
现在可以使用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'属性'"。 - Jonathan Hatchett
这个答案只是展示了如何生成密钥对,而不是问题所要求的。加密和解密仍然不受PyCryptodome支持。 - ThexXTURBOXx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接