Python和java的RSA加密解密
第⼀次⽤markdown写博客,看起来不错,⽤起来感觉⼀下吧。
⾔归正传,⼀个项⽬的需求是这样的:
服务器端使⽤python开发,⽣成⼀组1024bit的公钥和私钥。通过http把公钥交给android上的app(Java开发的)。App利⽤公钥加密⽤户名和密码,再Post到服务器上,服务器利⽤私钥解密然后验证,验证成功后给App⼀个Token。
其实就是⼀个保护⽤户登录的⼀个操作。
Python上RSA加密的库挺多的,最开始使⽤的是rsa,因为⽐较简单嘛!测试的时候也是⽤ python模拟App的访问,顺利通过!
然⽽App开发者反馈,python测试脚本没法移植到java上,因为java的加密解密模块需要更加精细的算法细节指定,否则java加密过的数据python是解不出来的。
当初就是因为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 = Instance(RSA_CONFIGURATION);
c.init(Cipher.DECRYPT_MODE, key, new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256,
PSource.PSpecified.DEFAULT));
byte[] decodedBytes;
decodedBytes = c.doFinal(Base64.Bytes("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 = Instance(RSA_CONFIGURATION);
c.init(Cipher.ENCRYPT_MODE, key, new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, PSource.PSpecifie
d.DEFAULT));
byte[] encodedBytes;
encodedBytes = c.Bytes("UTF-8"));
return de(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.Bytes("UTF-8"));
KeyFactory kf = Instance("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;
byte[] privateKeyBytes;
try {
privateKeyBytes = Base64.Bytes("UTF-8"));
KeyFactory kf = Instance("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();
python转java代码} 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.Bytes("UTF-8"));
KeyFactory kf = Instance("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 = Instance("RSA");
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(b1, b2);
return (RSAPublicKey) atePublic(keySpec);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
Python 代码
from Config import config
from Crypto.Hash import SHA256
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
key = ate(1024)
pubkey = key.publickey().key
def Decrypt(prikey,data):
try:
cipher = w(prikey, hashAlgo=SHA256)
return cipher.decrypt(data)
except:
traceback.print_exc()
return None
def Encrypt(pubkey,data):
try:
cipher = w(pubkey, hashAlgo=SHA256)
pt(data)
except:
traceback.print_exc()
return None
总结
主要是对RSA算法不是很熟悉,其中很多术语不懂,导致跟java⾥的加密模块的函数和类对应不上。
RSA算法的细节到现在也是⼀知半解,但真的没时间去深⼊学习了。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论