Recently I was doing python encryption and decryption. At the same time, the encrypted string can be solved on php. I also found some reliable information on the Internet. I just have time to summarize the python encryption and decryption code , May be used in the future. Compared to php, there are many encryption and decryption components in Python. They are:
python-crypto-This component is the basic component and the functions used are relatively complicated.
ezPyCrypto-Relatively simple, but he made "Miao Tombs", all lessons learned, and more sloppy? br /> SSLCrypto-ezPyCrypto was developed by the same author, and is more efficient than ezPyCrypto. But it is not compatible with other programs.
pyopenssl-seems to be used for https communication, and I can't find the usage of encryption and decryption.
M2Crypto-I finally found it, but it has a big shortcoming? It uses SWIG and OpenSSL to interface with it.
Installing the SWIG program on Windows is very difficult.
I chose to use M2Crypto. There are two ways to generate public and private key certificates, one is RSA generation, and the other is X509 generation. I will share these two encryption and decryption codes for your reference, but please indicate the source when reprinting or using it.
First, the certificate generated by the RSA standard method
1.Encryption and decryption, encryption signature, verification encryption signature
#encoding: utf8
import os
import M2Crypto
#Random number generator (1024-bit random)
M2Crypto.Rand.rand_seed (os.urandom (1024))
#Generate a 1024-bit public and private key certificate
Geekso = M2Crypto.RSA.gen_key (1024, 65537)
Geekso.save_key ('111cn.net-private.pem', None)
Geekso.save_pub_key ('111cn.net-public.pem')
#Start using public key certificate encryption
WriteRSA = M2Crypto.RSA.load_pub_key ('111cn.net-public.pem')
CipherText = WriteRSA.public_encrypt ("This is a secret message and can only be decrypted with a private key", M2Crypto.RSA.pkcs1_oaep_padding)
print "The encrypted string is:"
print CipherText.encode ('base64')
#Sign the encrypted string
MsgDigest = M2Crypto.EVP.MessageDigest ('sha1')
MsgDigest.update (CipherText)
#Hint, you can also use private key signature here
#WriteRSA = M2Crypto.RSA.load_key ('111cn.net-private.pem')
#Signature = WriteRSA.sign_rsassa_pss (MsgDigest.digest ())
Signature = Geekso.sign_rsassa_pss (MsgDigest.digest ())
print "Signed string is:"
print Signature.encode ('base64')
#Decrypt with private key certificate starts
ReadRSA = M2Crypto.RSA.load_key ('111cn.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)
#Hint, if it is signed with the private key, then use the public key to verify
#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 "Signed correctly"
else:
print "Incorrect signature"
2. String generation signature, verification signature
#Sign with private key
SignEVP = M2Crypto.EVP.load_key ('111cn.net-private.pem')
SignEVP.sign_init ()
SignEVP.sign_update ('Signature string from this guest (http://www.111cn.net)')
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 ('111cn.net-public.pem')
VerifyEVP = M2Crypto.EVP.PKey ()
VerifyEVP.assign_rsa (PubKey)
VerifyEVP.verify_init ()
VerifyEVP.verify_update ('Signature string from this guest (http://www.111cn.net)')
if VerifyEVP.verify_final (StringSignature) == 1:
print "The string was successfully verified."
else:
print "String validation failed!"
3. Add a password to the certificate
The advantage of adding a password to a certificate is that even if the certificate is taken, you can't use it without a password.
def passphrase (v):
return '4567890'
Used when generating a certificate
Geekso.save_key ('111cn.net-private.pem', callback = passphrase)
Use when using a certificate
ReadRSA = RSA.load_key ('111cn.net-private.pem', passphrase)
Second, the X509 standard generated certificate
1. Generate certificates, public key files, and private key files
import time
from M2Crypto import X509, EVP, RSA, ASN1
def issuer_name ():
"" "
Certificate issuer name (proprietary name).
Parameters:
none
Return:
X509 standard publisher obj.
"" "
issuer = X509.X509_Name ()
issuer.C = "CN" # country name
issuer.CN = "* .111cn.net" # common name
issuer.ST = "Hunan Changsha"
issuer.L = "Hunan Changsha"
issuer.O = "Geekso Company Ltd"
issuer.OU = "Geekso Company Ltd"
issuer.Email = "1085015507@qq.com"
return issuer
def make_request (bits, cn):
"" "
Create an X509 standard request.
Parameters:
bits = number of certificates
cn = certificate name
Return:
Returns 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 certificate is valid for a few days from the current time.
Parameters:
cert = certificate obj
days = number of days that the certificate expires
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 Certificate
Parameters:
bits = number of bits in the token
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) # serial number of the certificate
cert.set_version (1) # version of the certificate
cert.set_issuer (issuer_name ()) # issuer information
cert.set_subject (issuer_name ()) # subject information
cert.set_pubkey (puk)
make_certificate_valid_time (cert, 365) # Certificate expiration time
cert.sign (pk, 'sha256')
return cert, pk, puk
# Start to create
cert, pk, puk = make_certificate (1024)
cert.save_pem ('111cn.net-cret.pem')
pk.save_key ('111cn.net-private.pem', cipher = None, callback = lambda: None)
puk.get_rsa (). save_pub_key ('111cn.net-public.pem')
2. Use certificate encryption and private key file decryption
def geekso_encrypt_with_certificate (message, cert_loc):
"" "
The cert certificate is encrypted and can be decrypted with the private key file.
Parameters:
message = the string to be encrypted
cert_loc = cert certificate path
Return:
Encrypted string or exception 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.111cn.net', '111cn.net-cret.pem')
print 'encrypted string', encrypted
def geekso_decrypt_with_private_key (message, pk_loc):
"" "
Encrypted string generated by private key decryption 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)
except RSA.RSAError as e:
return "ERROR decrypting" + e.message
return decrypted
print 'decrypt string', geekso_decrypt_with_private_key (encrypted, '111cn.net-private.pem')
3. Use private key encryption and certificate decryption
def geekso_encrypt_with_private_key (message, pk_loc):
"" "
Private key encryption
Parameters:
message = encrypted string
pk_loc = private key path
Return:
Encrypted string or exception 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.111cn.net', '111cn.net-private.pem')
print encrypted
def geekso_decrypt_with_certificate (message, cert_loc):
"" "
cert certificate decryption.
Parameters:
message = the string to decrypt
cert_loc = cert certificate path
Return:
Decrypted string or exception 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, '111cn.net-cret.pem')
print decrypting
4.Sign with a private key and verify the signature with a certificate
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 string or exception 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.111cn.net', '111cn.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 = signed string
cert_loc = certificate path file
base64 = True (bease64 processing) False (hexadecimal processing)
Return:
Success or failure or exception
"" "
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 'success'
else:
return 'failure'
except EVP.EVPError as e:
return "ERROR Verify Sign" + e.message
print geekso_verifysign_with_certificate ('www.111cn.net', signature, '111cn.net-cret.pem')