Python certificate-based encryption and decryption implementation

Source: Internet
Author: User
This article mainly introduces the implementation method of python certificate-based encryption and decryption, and uses the M2Crypto component for related encryption and decryption operations, including the complete implementation process in detail, for more information about how to implement encryption and decryption with python certificates, see the example in this article. Share it with you for your reference. The specific implementation method is as follows:

Recently, I am working on the encryption and decryption of python. at the same time, I can solve the encrypted strings in php. I also found some reliable information on the Internet, just now I have summarized the python code for encryption and decryption, which may be useful in the future. Compared with php, python has many encryption and decryption components:

Python-crypto-this component is a basic component, and the function used is relatively complex.
EzPyCrypto-is relatively simple, but its public and private keys cannot be compatible with other programs. SSLCrypto-is developed by the same author as ezPyCrypto and is more efficient than ezPyCrypto. However, it cannot be compatible with other programs.
Pyopenssl-it seems to be used for https communication, but I cannot find the encryption and decryption usage.
M2Crypto-finally let me find it, but it has a major drawback that it uses SWIG to communicate with OpenSSL at the underlying layer.
Installing the SWIG Program in Windows is very difficult.

I chose to use M2Crypto. There are two ways to generate a public key and a private key certificate: RSA and X509. I will share the two encryption and decryption codes for your reference, but please indicate the source when reprinting or using them.

I. certificates generated in RSA standard mode

1. encryption and decryption, encryption and signature, and verification of encryption and signature

The code is as follows:

# Encoding: utf8
Import OS
Import M2Crypto
# Random number generator (1024-bit random)
M2Crypto. Rand. rand_seed (OS. urandom (1024 ))
# Generate a 1024-bit public key and private key certificate
Geekso = M2Crypto. RSA. gen_key (1024,655 37)
Geekso. save_key ('jb51. net-private.pem ', None)
Geekso. save_pub_key ('jb51. net-public.pem ')
# Start with public key certificate encryption
WriteRSA = M2Crypto. RSA. load_pub_key ('jb51. net-public.pem ')
CipherText = WriteRSA. public_encrypt ("This is a private message and can only be decrypted using the private key", M2Crypto. RSA. pkcs1_oaep_padding)
Print "the encrypted string is :"
Print CipherText. encode ('base64 ')
# Sign an encrypted string
MsgDigest = M2Crypto. EVP. MessageDigest ('sha1 ')
MsgDigest. update (CipherText)
# Note: You can use the private key signature here.
# WriteRSA = M2Crypto. RSA. load_key ('jb51. net-private.pem ')
# Signature = WriteRSA. sign_rsassa_pss (MsgDigest. digest ())
Signature = Geekso. sign_rsassa_pss (MsgDigest. digest ())
Print "the signature string is :"
Print Signature. encode ('base64 ')
# Start decryption with the private key certificate
ReadRSA = M2Crypto. RSA. load_key ('jb51. net-private.pem ')
Try:
PlainText = ReadRSA. private_decrypt (CipherText, M2Crypto. RSA. pkcs1_oaep_padding)
Except t:
Print "decryption error"
PlainText = ""
If PlainText:
Print "the decrypted string is :"
Print PlainText
# Verify the signature of the encrypted string
MsgDigest = M2Crypto. EVP. MessageDigest ('sha1 ')
MsgDigest. update (CipherText)
# Tips: If the private key is used for signature, use the public key for verification.
# VerifyRSA = M2Crypto. RSA. load_pub_key ('Alice-public. pem ')
# VerifyRSA. verify_rsassa_pss (MsgDigest. digest (), Signature)
If Geekso. verify_rsassa_pss (MsgDigest. digest (), Signature) = 1:
Print "correct signature"
Else:
Print "incorrect signature"

2. Generate and verify the signature using a string

The code is as follows:

# Private key signature
SignEVP = M2Crypto. EVP. load_key ('jb51. net-private.pem ')
SignEVP. sign_init ()
SignEVP. sign_update ('signature string from this customer (http://www.jb51.net ')
StringSignature = SignEVP. sign_final ()
Print "signature string :"
Print StringSignature. encode ('base64 ')
# Use the public key to verify the signature
PubKey = M2Crypto. RSA. load_pub_key ('jb51. net-public.pem ')
VerifyEVP = M2Crypto. EVP. PKey ()
VerifyEVP. assign_rsa (PubKey)
VerifyEVP. verify_init ()
VerifyEVP. verify_update ('signature string from this customer (http://www.jb51.net ')
If VerifyEVP. verify_final (StringSignature) = 1:
Print "string verified. "
Else:
Print "string verification failed! "

3. add a password to the certificate

The advantage of adding a password to the certificate is that even if the certificate is taken by someone, it cannot be used without a password.

The code is as follows:

Def passphrase (v ):
Return '20140901'


Used to generate a certificate

The code is as follows:

Geekso. save_key ('jb51. net-private.pem ', callback = passphrase)


Use the certificate

The code is as follows:

ReadRSA = RSA. load_key ('jb51. net-private.pem ', passphrase)


II. certificate generated in X509 standard mode

1. Generate certificates, public key files, and private key files

The code is as follows:

Import time
From M2Crypto import X509, EVP, RSA, ASN1
Def issuer_name ():
"""
Certificate issuer name (private name ).
Parameters:
None
Return:
X509 standard issuer obj.
"""
Issuer = X509.X509 _ Name ()
Issuer. C = "CN" # country name
Issuer. CN = "* .jb51.net" # normal name
Issuer. ST = "Hunan Changsha"
Issuer. L = "Hunan Changsha"
Issuer. O = "Geekso Company Ltd"
Issuer. OU = "Geekso Company Ltd"
Issuer. Email = "123456@qq.com"
Return issuer
Def make_request (bits, cn ):
"""
Create an X509 standard request.
Parameters:
Bits = certificate count
Cn = certificate name
Return:
Returns the X509 request and private key (EVP ).
"""
Rsa = RSA. gen_key (bits, 65537, None)
Pk = EVP. PKey ()
Pk. assign_rsa (rsa)
Req = X509.Request ()
Req. set_pubkey (pk)
Name = req. get_subject ()
Name. C = "US"
Name. CN = cn
Req. sign (pk, 'sha256 ')
Return req, pk
Def make_certificate_valid_time (cert, days ):
"""
The validity period of the certificate is several days from the current time.
Parameters:
Cert = certificate obj
Days = days when the certificate expires
Return:
None
"""
T = long (time. time () # obtain the current time
Time_now = ASN1.ASN1 _ UTCTIME ()
Time_no1_set_time (t)
Time_exp = ASN1.ASN1 _ UTCTIME ()
Time_exp.set_time (t + days * 24*60*60)
Cert. set_not_before (time_now)
Cert. set_not_after (time_exp)
Def make_certificate (bits ):
"""
Create certificate
Parameters:
Bits = bits
Return:
Certificate, private key (EVP) and public key (EVP ).
"""
Req, pk = make_request (bits, "localhost ")
Puk = req. get_pubkey ()
Cert = X509.X509 ()
Cert. set_serial_number (1) # certificate sequence number
Cert. set_version (1) # certificate version
Cert. set_issuer (issuer_name () # issuer information
Cert. set_subject (issuer_name () # topic information
Cert. set_pubkey (puk)
Make_certificate_valid_time (cert, 365) # certificate expiration time
Cert. sign (pk, 'sha256 ')
Return cert, pk, puk
# Start creation
Cert, pk, puk = make_certificate (1024)
Cert. save_pem ('jb51. net-cret.pem ')
Pk. save_key ('jb51. net-private.pem ', cipher = None, callback = lambda: None)
Puk. get_rsa (). save_pub_key ('jb51. net-public.pem ')

2. use certificate encryption and private key file decryption

The code is as follows:

Def geekso_encrypt_with_certificate (message, cert_loc ):
"""
The cert certificate is encrypted and can be decrypted using the private key file.
Parameters:
Message = string to be encrypted
Cert_loc = cert certificate path
Return:
Encrypted or abnormal string
"""
Cert = X509.load _ cert (cert_loc)
Puk = cert. get_pubkey (). get_rsa () # get RSA for encryption
Message = base64.b64encode (message)
Try:
Encrypted = puk. public_encrypt (message, RSA. pkcs1_padding)
Failed t rsa. RSAError as e:
Return "ERROR encrypting" + e. message
Return encrypted
Encrypted = geekso_encrypt_with_certificate ('www .jb51.net', 'jb51. net-cret.pem ')
Print 'encrypted string', encrypted
Def geekso_decrypt_with_private_key (message, pk_loc ):
"""
Private key decrypts the encrypted string generated by the certificate
Parameters:
Message = encrypted string
Pk_loc = private key path
Return:
Decryption string or exception string
"""
Pk = RSA. load_key (pk_loc) # load RSA for decryption
Try:
Decrypted = pk. private_decrypt (message, RSA. pkcs1_padding)
Decrypted = base64.b64decode (decrypted)
Failed t rsa. RSAError as e:
Return "ERROR decrypting" + e. message
Return decrypted
Print 'decryption string', geekso_decrypt_with_private_key (encrypted, 'jb51. net-private.pem ')

3. use the private key for encryption and certificate decryption

The code is as follows:

Def geekso_encrypt_with_private_key (message, pk_loc ):
"""
Private key encryption
Parameters:
Message = encrypted string
Pk_loc = private key path
Return:
Encrypted or abnormal string
"""
ReadRSA = RSA. load_key (pk_loc );
Message = base64.b64encode (message)
Try:
Encrypted = ReadRSA. private_encrypt (message, RSA. pkcs1_padding)
Failed t rsa. RSAError as e:
Return "ERROR encrypting" + e. message
Return encrypted
Encrypted = geekso_encrypt_with_private_key ('www .jb51.net', 'jb51. net-private.pem ')
Print encrypted
Def geekso_decrypt_with_certificate (message, cert_loc ):
"""
Decrypt the cert certificate.
Parameters:
Message = string to be decrypted
Cert_loc = cert certificate path
Return:
Decrypted or abnormal string
"""
Cert = X509.load _ cert (cert_loc)
Puk = cert. get_pubkey (). get_rsa ()
Try:
Decrypting = puk. public_decrypt (message, RSA. pkcs1_padding)
Decrypting = base64.b64decode (decrypting)
Failed t rsa. RSAError as e:
Return "ERROR decrypting" + e. message
Return decrypting
Decrypting = geekso_decrypt_with_certificate (encrypted, 'jb51. net-cret.pem ')
Print decrypting

4. use the private key signature and certificate to verify the signature

The code is as follows:

Def geekso_sign_with_private_key (message, pk_loc, base64 = True ):
"""
Private key signature
Parameters:
Message = string to be signed
Pk_loc = private key path
Base64 = True (bease64 processing) False (hexadecimal processing)
Return:
Signed or abnormal string
"""
Pk = EVP. load_key (pk_loc)
Pk. sign_init ()
Try:
Pk. sign_update (message)
Signature = pk. sign_final ()
Except t EVP. EVPError as e:
Return "ERROR signature" + e. message
Return signature. encode ('base64') if base64 is True else signature. encode ('Hex ')
Signature = geekso_sign_with_private_key ('www .jb51.net', 'jb51. net-private.pem ')
Print signature
Def geekso_verifysign_with_certificate (message, signature, cert_loc, base64 = True ):
"""
Certificate verification signature
Parameters:
Message = original signature string
Signature = signature string
Cert_loc = certificate Path File
Base64 = True (bease64 processing) False (hexadecimal processing)
Return:
Successful or failed or abnormal
"""
Signature = signature. decode ('base64') if base64 is True else signature. decode ('Hex ')
Cert = X509.load _ cert (cert_loc)
Puk = cert. get_pubkey (). get_rsa ()
Try:
VerifyEVP = EVP. PKey ()
VerifyEVP. assign_rsa (puk)
VerifyEVP. verify_init ()
VerifyEVP. verify_update (message)
Verifysign = verifyEVP. verify_final (signature)
If verifysign = 1:
Return 'successfully'
Else:
Return 'failed'
Except t EVP. EVPError as e:
Return "ERROR Verify Sign" + e. message

Print geekso_verifysign_with_certificate ('www .jb51.net', signature, 'jb51. net-cret.pem ')

I hope this article will help you with Python programming.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.