Python has a certificate of encryption and decryption implementation method
- 2020-04-02 14:20:52
- OfStack
This article illustrates the implementation of cryptographic decryption with certificate in python. Share with you for your reference. The specific implementation method is as follows:
Recently, I have been doing the encryption and decryption work of python. At the same time, the encrypted string can be solved in PHP. I also found some reliable materials on the Internet. Compared with PHP, python has more encryption and decryption components, which are:
Python -crypto - this component is a basic component and USES relatively complex functions.
EzPyCrypto - relatively simple, but it makes public and private keys that are not compatible with other programs
SSLCrypto - with ezPyCrypto is the same as an author development, efficiency is better than ezPyCrypto. But it is not compatible with other programs.
Pyopenssl - appears to be used for HTTPS communications, and I can't find encryption or decryption.
M2Crypto - I finally found it, but it has one big drawback: it USES SWIG to interface with OpenSSL.
Installing SWIG on Windows is very difficult.
I choose to use M2Crypto. There are two ways to generate public key and private key certificates, one is generated by RSA, the other is generated by X509. I put these two encryption and decryption code to share out, for your reference, but reprint or use please note the source.
One, RSA standard way to generate the certificate
1. Encrypt and decrypt, encrypt and verify the signature
#encoding: utf8
import os
import M2Crypto
# Random number generator (1024 A random )
M2Crypto.Rand.rand_seed(os.urandom(1024))
# To generate a 1024 Bit public key and private key certificate
Geekso = M2Crypto.RSA.gen_key(1024, 65537)
Geekso.save_key('jb51.net-private.pem', None)
Geekso.save_pub_key('jb51.net-public.pem')
# Encryption begins with the public key certificate
WriteRSA = M2Crypto.RSA.load_pub_key('jb51.net-public.pem')
CipherText = WriteRSA.public_encrypt(" This is a secret message , Decryption can only be done with the private key ",M2Crypto.RSA.pkcs1_oaep_padding)
print " The encrypted string is :"
print CipherText.encode('base64')
# The encrypted string is signed
MsgDigest = M2Crypto.EVP.MessageDigest('sha1')
MsgDigest.update(CipherText)
# Note that you can also sign using a private key
#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')
# Decryption begins 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:
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)
# Note that if it is signed with a private key, use public key authentication
#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 " Signature right "
else:
print " Incorrect signature "
2. Generate and verify the signature of the string
# Sign with the private key
SignEVP = M2Crypto.EVP.load_key('jb51.net-private.pem')
SignEVP.sign_init()
SignEVP.sign_update(' From this guest (//www.jb51.net) signature string ')
StringSignature = SignEVP.sign_final()
print " Signature string is :"
print StringSignature.encode('base64')
# Verify the signature with the public key
PubKey = M2Crypto.RSA.load_pub_key('jb51.net-public.pem')
VerifyEVP = M2Crypto.EVP.PKey()
VerifyEVP.assign_rsa(PubKey)
VerifyEVP.verify_init()
VerifyEVP.verify_update(' From this guest (//www.jb51.net) signature string ')
if VerifyEVP.verify_final(StringSignature) == 1:
print " The string was successfully validated. "
else:
print " String validation failed !"
3. Pin the certificate
The advantage of adding a password to a certificate is that even if the certificate is taken, it cannot be used without a password.
def passphrase(v):
return '4567890'
Used to generate a certificate
Geekso.save_key('jb51.net-private.pem',callback=passphrase)
When using a certificate
ReadRSA = RSA.load_key ('jb51.net-private.pem', passphrase)
Ii. X509 standard certificate
1. Generate certificates, public key files and private key files
import time
from M2Crypto import X509, EVP, RSA, ASN1
def issuer_name():
"""
Name of certificate issuer ( Distinguished name (dn) ) .
Parameters:
none
Return:
X509 Standard issuer obj.
"""
issuer = X509.X509_Name()
issuer.C = "CN" # State the name of the
issuer.CN = "*.jb51.net" # Common names
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):
"""
To create a X509 Standard request.
Parameters:
bits = The certificate number
cn = Name of the certificate
Return:
return X509 request with 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 certificate is valid for a few days from the current date.
Parameters:
cert = certificate obj
days = The number of days the certificate has expired
Return:
none
"""
t = long(time.time()) # Get the current time
time_now = ASN1.ASN1_UTCTIME()
time_now.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 a certificate
Parameters:
bits = The number of digits of the card speed
Return:
certificate , The private key key (EVP) with The public key key (EVP).
"""
req, pk = make_request(bits, "localhost")
puk = req.get_pubkey()
cert = X509.X509()
cert.set_serial_number(1) # The order number of the certificate
cert.set_version(1) # Version of certificate
cert.set_issuer(issuer_name()) # Issuer information
cert.set_subject(issuer_name()) # Topic information
cert.set_pubkey(puk)
make_certificate_valid_time(cert, 365) # The expiration date of the certificate
cert.sign(pk, 'sha256')
return cert, pk, puk
# Start to create
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. Encrypt and decrypt files with certificates and private keys
def geekso_encrypt_with_certificate(message, cert_loc):
"""
cert The certificate is encrypted and can be decrypted using a private key file .
Parameters:
message = The string to be encrypted
cert_loc = cert The certificate path
Return:
Encrypted string 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)
except 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):
"""
The private key decrypts the encrypted string generated by the certificate
Parameters:
message = Encrypted string
pk_loc = The private key path
Return:
Decrypt the string or Abnormal string
"""
pk = RSA.load_key(pk_loc) # load RSA for decryption
try:
decrypted = pk.private_decrypt(message, RSA.pkcs1_padding)
decrypted = base64.b64decode(decrypted)
except RSA.RSAError as e:
return "ERROR decrypting " + e.message
return decrypted
print ' Decrypt the string ',geekso_decrypt_with_private_key(encrypted, 'jb51.net-private.pem')
3. Use private key to encrypt and certificate to decrypt
def geekso_encrypt_with_private_key(message,pk_loc):
"""
The private key encryption
Parameters:
message = Encrypted string
pk_loc = The private key path
Return:
Encrypted string or Abnormal string
"""
ReadRSA = RSA.load_key(pk_loc);
message = base64.b64encode(message)
try:
encrypted = ReadRSA.private_encrypt(message,RSA.pkcs1_padding)
except 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):
"""
cert Certificate of decryption .
Parameters:
message = The string to be decrypted
cert_loc = cert The certificate path
Return:
Decrypted string 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)
except RSA.RSAError as e:
return "ERROR decrypting " + e.message
return decrypting
decrypting = geekso_decrypt_with_certificate(encrypted, 'jb51.net-cret.pem')
print decrypting
4. Verify the signature with private key and certificate
def geekso_sign_with_private_key(message, pk_loc, base64 = True):
"""
The private key signature
Parameters:
message = A string to be signed
pk_loc = The private key path
base64 = True(bease64 To deal with ) False(16 Into the system to deal with )
Return:
The signed string or Abnormal string
"""
pk = EVP.load_key(pk_loc)
pk.sign_init()
try:
pk.sign_update(message)
signature = pk.sign_final()
except 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 = The original signed string
signature = The signed string
cert_loc = Certificate path file
base64 = True(bease64 To deal with ) False(16 Into the system to deal with )
Return:
successful or Failure string or Abnormal string
"""
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 ' successful '
else :
return ' failure '
except 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 has helped you with your Python programming.