Python的加密方式:RSA加密
Python的加密方式:RSA加密
RSA加密是一种非对称加密,通常使用公钥加密,私钥解密,私钥签名,公钥验签。
在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的.RSA算法通常是先生成一对RSA密钥,其中之一是保密密钥,由用户保存;另一个为公开密钥,可对外公开,甚至可在网络服务器中注册。
RSA是一种公钥密码算法,加密算法是将明文m(m<n是一个整数)加密成密文c,即明文数字m的 E 次方求mod N,也就是将明文与自己相乘E次,然后结果除以N求余数,余数就是密文c,E和N组合就是公钥;解密算法为将密文c解密为明文m,即密文数字c的D次方求mod N,也就是将密文与自己相乘D次,然后结果除以N求余数,余数就是明文m,D和N组合就是私钥。
以下是关于RSA生成公钥私钥、加密、解密、加签、验签的示例。
1、生成公钥私钥:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | from Crypto import Random from Crypto.PublicKey import RSA # 伪随机数生成器 random_generator = Random.new().read # rsa算法生成实例 rsa = RSA.generate( 1024 , random_generator) # 私钥的生成 private_pem = rsa.exportKey() with open ( "private.pem" , "wb" ) as f: f.write(private_pem) # 公钥的生成 public_pem = rsa.publickey().exportKey() with open ( "public.pem" , "wb" ) as f: f.write(public_pem) |
生成的公钥私钥文件在项目路径下,也可以直接指定生成文件路径。
文件样例:
生成的公钥私钥格式是固定的,秘钥中间无空格无换行,秘钥末尾也空格无换行,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | - - - - - BEGIN PUBLIC KEY - - - - - MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDEedv + 5NsbqAh6pjOMKF8I7FGa et3QMUi0g5xDfQAM219qqXnoPi2hmCMjR8MWJV / zyMZ6IiRG / pvrZ2ZhfDNFdW3Z SfHczRUvabABzWAr / 57 / eDBjswv4RQA + gUS6t8wFY / iV + O3i9 + d79iN3VhUogfI3 3Ru3 + RPFeFW88tYUhwIDAQAB - - - - - END PUBLIC KEY - - - - - - - - - - BEGIN RSA PRIVATE KEY - - - - - MIICXAIBAAKBgQDEedv + 5NsbqAh6pjOMKF8I7FGaet3QMUi0g5xDfQAM219qqXno Pi2hmCMjR8MWJV / zyMZ6IiRG / pvrZ2ZhfDNFdW3ZSfHczRUvabABzWAr / 57 / eDBj swv4RQA + gUS6t8wFY / iV + O3i9 + d79iN3VhUogfI33Ru3 + RPFeFW88tYUhwIDAQAB AoGAApzaO5QAg + gioLroEZOR2 / UEisjafUPCg0ACynT1lLYwGSOCzv9QrQbwZK42 HmvF0GCZnxMoJ1eIbEN2PZKgveQ / o4o8OdhuSk8pcDY72QwQHgSh1yfdvqkulo7D vdmjz63DVSrknYRQFYSHIwUPVVTWyT80OTCYSn3JGqNKa9kCQQDZUbtlBvcPzP4T 5hRaH9XvCh3PPusQKGPzVRVLn + qZ30N2PNgttYKRMshlz1WMts2ZAKr3b3BLT6GT shE5KatfAkEA53JkuV1vUEMg5j1ClgrwTs65yLWb + NbLH84xekrkkSxCkVjE7J / N QV7Uk87na49LuztBaECBmaZyTQnFKk7P2QJAMzcc18lVbmbcNipR / 49jJquWrOHi GfO64nzZwPHWIx9H0dSzCcquE7QJIF1Fhx0JxRYwNJIRv93rcVhU0MjuNwJAIgI / JrXCC4sxpGNQC3gkA5CA4Cs / dfsp8cx8nLmwiFx2k6D1nseEg5yJpAZ9HuL5f9Of MtB3uroohYVwAV1 / UQJBAIZQkryoOJxPbfWvIIGBOAlS / QqfE5kLV + 3L2RUtBlac nJykMucrdDx1gVKgoREUElxpYtlWI17h9MeNXRICgIM = - - - - - END RSA PRIVATE KEY - - - - - |
2、加密(使用公钥加密)
1 2 3 4 5 6 7 8 9 10 | from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5 import base64 # 加密 message = "Hello,This is RSA加密" rsakey = RSA.importKey( open ( "public.pem" ).read()) cipher = Cipher_pkcs1_v1_5.new(rsakey) #创建用于执行pkcs1_v1_5加密或解密的密码 cipher_text = base64.b64encode(cipher.encrypt(message.encode( 'utf-8' ))) print (cipher_text.decode( 'utf-8' )) |
加密结果:
1 | Y1oivzbBDIEWX + NaXYLCJo5A226TmuemketZMUM3U80Rw3gSETjG5rHQ + S + + Yao + iGQ5jSJA2yjkDtDAjdvi2VUz15LRSkdeKoliWnWy93KKl + aNEsBl3SUicATUgfNWU5ILo + DiltpF79AfIEhPptAz7 + gN11KAf5LjfcQZ2 + 0 = |
这里每次使用公钥加密后的结果都不一致,跟对数据的padding即填充有关。
加密时支持的最大字节数与证书有一定关系。加密时支持的最大字节数:证书位数/8 -11(比如:2048位的证书,支持的最大加密字节数:2048/8 - 11 = 245)
1024位的证书,加密时最大支持117个字节,解密时为128;
2048位的证书,加密时最大支持245个字节,解密时为256。
如果需要加密的字节数超出证书能加密的最大字节数,此时就需要进行分段加密。
3、解密(使用私钥解密)
1 2 3 4 5 6 7 8 9 10 11 | from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5 import base64 # 解密 cipher_text = "Y1oivzbBDIEWX+NaXYLCJo5A226TmuemketZMUM3U80Rw3gSETjG5rHQ+S++Yao+iGQ5jSJA2yjkDtDAjdvi2VUz15LRSkdeKoliWnWy93KKl+aNEsBl3SUicATUgfNWU5ILo+DiltpF79AfIEhPptAz7+gN11KAf5LjfcQZ2+0=" encrypt_text = cipher_text.encode( 'utf-8' ) rsakey = RSA.importKey( open ( "private.pem" ).read()) cipher = Cipher_pkcs1_v1_5.new(rsakey) #创建用于执行pkcs1_v1_5加密或解密的密码 text = cipher.decrypt(base64.b64decode(encrypt_text), "解密失败" ) print (text.decode( 'utf-8' )) |
解密结果,与加密前信息一致:
1 | Hello,This is RSA加密 |
4、加签(使用私钥加签)
使用私钥加签,每次签名是一致的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | from Crypto.PublicKey import RSA from Crypto.Signature import PKCS1_v1_5 as Signature_pkcs1_v1_5 from Crypto. Hash import SHA import base64 #加签 message = "This is a request message..." rsakey = RSA.importKey( open ( "private.pem" ).read()) signer = Signature_pkcs1_v1_5.new(rsakey) digest = SHA.new() digest.update(message.encode( "utf-8" )) sign = signer.sign(digest) signature = base64.b64encode(sign) print (signature.decode( 'utf-8' )) |
签名结果:
1 | fd99fQpbH48VT9YQKepyHSip9pwrJkm1PN3ZykHNrfTVk555fv392E7MtbIfcligOCWUx8nd3g + 7J0Fo3x + 9G1Y6MJs0CuMCbA4qulUMNGjzUpsN1URorMZfPKjPvhf22ARH9qZEnebQ7UUGO3ioy4nylZONb3Ldhga + PKyxYTM = |
5、验签(使用公钥验签)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | from Crypto.PublicKey import RSA from Crypto.Signature import PKCS1_v1_5 as Signature_pkcs1_v1_5 from Crypto. Hash import SHA import base64 #验签 message_verify = "This is a request message..." signature = "fd99fQpbH48VT9YQKepyHSip9pwrJkm1PN3ZykHNrfTVk555fv392E7MtbIfcligOCWUx8nd3g+7J0Fo3x+9G1Y6MJs0CuMCbA4qulUMNGjzUpsN1URorMZfPKjPvhf22ARH9qZEnebQ7UUGO3ioy4nylZONb3Ldhga+PKyxYTM=" rsakey = RSA.importKey( open ( "public.pem" ).read()) verifier = Signature_pkcs1_v1_5.new(rsakey) hsmsg = SHA.new() hsmsg.update(message_verify.encode( "utf-8" )) is_verify = verifier.verify(hsmsg, base64.b64decode(signature)) print (is_verify) |
验签结果:
1 | True |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步