用python加密的可以用java解密吗

如题所述

第1个回答  2017-11-03
服务器端使用python开发,生成一组1024bit的公钥和私钥。通过http把公钥交给android上的app(Java开发的)。App利用公钥加密用户名和密码,再Post到服务器上,服务器利用私钥解密然后验证,验证成功后给App一个Token。
其实就是一个保护用户登录的一个操作。
Python上RSA加密的库挺多的,最开始使用的是rsa,因为比较简单嘛!测试的时候也是用 python模拟App的访问,顺利通过!
然而App开发者反馈,python测试脚本没法移植到java上,因为java的加密解密模块需要更加精细的算法细节指定,否则java加密过的数据python是解不出来的。
当初就是因为rsa模块简单,不需要注重细节才选的,自己又不是专业搞加密解密的。没办法了,只能硬着头皮,捋了一遍RSA的加密原理。网上还是有比较多的讲述比较好的文章,比如RSA算法原理
原理是懂了,但具体到python和java的区别上,还是一头雾水。最终python的RSA模块换成Crypto,因为支持的参数比较多。搜了很多网站讲的都不是很详细,stackflow上有几篇还可以,借鉴了一下,最后测试通过了。还是直接上代码吧。
Java代码
//下面这行指定了RSA算法的细节,必须更python对应
private static String RSA_CONFIGURATION = "RSA/ECB/OAEPWithSHA-256AndMGF1Padding"; //这个貌似需要安装指定的provider模块,这里没有使用
private static String RSA_PROVIDER = "BC"; //解密 Key:私钥
public static String decrypt(Key key, String encryptedString){ try {
Cipher c = Cipher.getInstance(RSA_CONFIGURATION);
c.init(Cipher.DECRYPT_MODE, key, new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256,
PSource.PSpecified.DEFAULT)); byte[] decodedBytes;
decodedBytes = c.doFinal(Base64.decode(encryptedString.getBytes("UTF-8"))); return new String(decodedBytes, "UTF-8");
} catch (IllegalBlockSizeException e) { // TODO Auto-generated catch block
e.printStackTrace();
} catch (BadPaddingException e) { // TODO Auto-generated catch block
e.printStackTrace();
} catch (Base64DecodingException e) { // TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) { // TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeyException e) { // TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) { // TODO Auto-generated catch block
e.printStackTrace();
} return null;
} //加密 Key一般是公钥public static String encrypt(Key key, String toBeEncryptedString){ try {
Cipher c = Cipher.getInstance(RSA_CONFIGURATION);
c.init(Cipher.ENCRYPT_MODE, key, new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256,
PSource.PSpecified.DEFAULT)); byte[] encodedBytes;
encodedBytes = c.doFinal(toBeEncryptedString.getBytes("UTF-8")); return Base64.encode(encodedBytes);
} catch (IllegalBlockSizeException e) { // TODO Auto-generated catch block
e.printStackTrace();
} catch (BadPaddingException e) { // TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) { // TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeyException e) { // TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) { // TODO Auto-generated catch block
e.printStackTrace();
} return null;
} //通过Pem格式的字符串(PKCS8)生成私钥,base64是去掉头和尾的b64编码的字符串
//Pem格式私钥一般有2种规范:PKCS8和PKCS1.注意java在生成私钥时的不同
static PrivateKey generatePrivateKeyFromPKCS8(String base64)
{ byte[] privateKeyBytes; try {
privateKeyBytes = Base64.decode(base64.getBytes("UTF-8"));
KeyFactory kf = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec ks = new PKCS8EncodedKeySpec(privateKeyBytes);
PrivateKey privateKey = kf.generatePrivate(ks); return privateKey;
} catch (Base64DecodingException e) { // TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeySpecException e) { // TODO Auto-generated catch block
e.printStackTrace();
} return null;
} //通过Pem格式的字符串(PKCS1)生成私钥,base64是去掉头和尾的b64编码的字符串
static PrivateKey generatePrivateKeyFromPKCS1(String base64)
{ byte[] privateKeyBytes; try {
privateKeyBytes = Base64.decode(base64.getBytes("UTF-8"));
KeyFactory kf = KeyFactory.getInstance("RSA");
X509EncodedKeySpec ks = new X509EncodedKeySpec(privateKeyBytes);
PrivateKey privateKey = kf.generatePrivate(ks); return privateKey;
} catch (Base64DecodingException e) { // TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeySpecException e) { // TODO Auto-generated catch block
e.printStackTrace();
} return null;
} //通过Pem格式的字符串(PKCS1)生成公钥,base64是去掉头和尾的b64编码的字符串
//Pem格式公钥一般采用PKCS1格式
static PublicKey generatePublicKeyFromPKCS1(String base64)
{ byte[] publicKeyBytes; try {
publicKeyBytes = Base64.decode(base64.getBytes("UTF-8"));
KeyFactory kf = KeyFactory.getInstance("RSA");
X509EncodedKeySpec ks = new X509EncodedKeySpec(publicKeyBytes);
PublicKey publicKey = kf.generatePublic(ks); return publicKey;
} catch (Base64DecodingException e) { // TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeySpecException e) { // TODO Auto-generated catch block
e.printStackTrace();
} return null;
} //通过modulus和exponent生成公钥
//参数含义就是RSA算法里的意思
public static RSAPublicKey getPublicKey(String modulus, String exponent) {
try {
BigInteger b1 = new BigInteger(modulus);
BigInteger b2 = new BigInteger(exponent);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(b1, b2);
return (RSAPublicKey) keyFactory.generatePublic(keySpec);
} catch (Exception e) {
e.printStackTrace();
return null;
}
} 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169

Python 代码
from Config import configfrom Crypto.Hash import SHA256from Crypto.PublicKey import RSAfrom Crypto.Cipher import PKCS1_OAEP

key = RSA.generate(1024)
pubkey = key.publickey().keydef Decrypt(prikey,data):
try:
cipher = PKCS1_OAEP.new(prikey, hashAlgo=SHA256) return cipher.decrypt(data) except:
traceback.print_exc() return Nonedef Encrypt(pubkey,data):
try:
cipher = PKCS1_OAEP.new(pubkey, hashAlgo=SHA256) return cipher.encrypt(data) except:
traceback.print_exc() return None本回答被提问者采纳
第2个回答  2018-04-26

对 Python 加密时可能会有两种形式,一种是对Python转成的exe进行保护,另一种是直接对.py或者.pyc文件进行保护,下面将列举两种形式的保护流程。

1、 对 python转exe加壳

下载最新版Virbox Protector加壳工具,使用加壳工具直接对demo.exe进行加壳操作

2、对.py/.pyc加密

第一步,使用加壳工具对 python 安装目录下的 python.exe 进行加壳,将 python.exe 拖入到加壳工具 VirboxProtector 中,配置后直接点击加壳。

第二步,对.py/.pyc 进行加密,使用 DSProtector 对.py/.pyc 进行保护。

安全技术:

l 虚拟机外壳:精锐5的外壳保护工具,创新性的引入了预分析和自动优化引擎,有效的解决了虚拟化保护代码时的安全性和性能平衡问题。

l 碎片代码执行:利用自身成熟的外壳中的代码提取技术,抽取大量、大段代码,加密混淆后在安全环境中执行,最大程度上减少加密锁底层技术和功能的依赖,同时大量大段地移植又保证了更高的安全性。

l Virbox加密编译引擎:集编译、混淆等安全功能于一身,由于在编译阶段介入,可优化空间是普遍虚拟化技术无法比拟的,对代码、变量的混淆程度也有了根本的提升。

l 反黑引擎:内置R0级核心态反黑引擎,基于黑客行为特征 的(反黑数据库)反制手段。精准打击调试、注入、内存修改等黑客行为,由被动挨打到主动防护。

加密效果:

加密之前

以pyinstall 的打包方式为例,使用pyinstxtractor.py文件对log_322.exe进行反编译,执行后会生成log_322.exe_extracted文件夹,文件夹内会生成pyc文件。

成功之后会在同目录下生成一个文件夹

使用010 Editor添加几个字节,重命名为pyc文件

注【此处和python的版本有关,Python27的可以直接解压为pyc文件,Python34还需要添加几个字节】

然后使用EasyPython Decompiler 工具反编译pyc

成功之后通目录下会生成dis文件,生成出的dis文件可以用文本编辑器打开,看到源码

反编译后的log_322.exe的源码

加密之后:

【注:不同的打包方式原理不同,源码存放的位置也不同,所以需要保护的具体模块也是不同的】

加密之后再尝试解压log322.exe失败,已经无法进行反编译,使用常规反编译工具也是无法进行分析的。

相似回答