Android RSA加密与解密开发总结(可以与c#的RSA加密解密互通)
2013-09-09 16:23
756 查看
[align=left]Java中有很好的rsa加密与解密类库,同样这些类库也被迁移到了Android的api中,但稍有不同,在java中的base64编码和解码api与Android稍有不同,Android只是简化了一部分操作。如下就将Android中常用的加密和解密的方法总结如下:[/align]
//设置使用何种加密算法
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
// 密钥位数
keyPairGen.initialize(1024);
// 密钥对
KeyPair keyPair = keyPairGen.generateKeyPair();
// 公钥
PublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
// 私钥
PrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
复制代码
以上api需要引入以下的包
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
复制代码
为了公钥跟私钥可以传输和保存,因此可以设置为将他们转化成base64的编码,用到以下方法:
/****************************************
* 函数说明:getKeyString 根据key得到64位加密字符串
*
* @param key 密钥
* @throws Exception
* @return String 加密后的字符串
* @author 王洪贺 2013-8-21
***************************************/
public static String getKeyString(Key key) throws Exception
{
byte[] keyBytes = key.getEncoded();
String s = base64Enc(keyBytes);
return s;
}
复制代码
但加密跟解密的时候需要将base64位的编码转化为key的对象,所以用到以下两个方法:
/****************************************
* 函数说明:getPublicKey 取得公钥
*
* @param key 公钥字符串
* @throws Exception
* @return PublicKey 返回公钥
* @author 王洪贺 2013-8-21
***************************************/
public static PublicKey getPublicKey(String key) throws Exception
{
byte[] keyBytes;
keyBytes = base64Dec(key);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(keySpec);
return publicKey;
}
/****************************************
* 函数说明:getPrivateKey 取得私钥
*
* @param key 私钥字符串
* @throws Exception
* @return PrivateKey 返回私钥
* @author 王洪贺 2013-8-21
***************************************/
public static PrivateKey getPrivateKey(String key) throws Exception
{
byte[] keyBytes;
keyBytes = base64Dec(key);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
return privateKey;
}
复制代码
下面就是加密过程,很简单:
// 实例化加解密类
Cipher cipher = Cipher.getInstance("RSA");
// 明文
byte[] plainText = "明文".getBytes();
// 加密
cipher.init(Cipher.ENCRYPT_MODE, publicKe);
//将明文转化为根据公钥加密的密文,为byte数组格式
byte[] enBytes = cipher.doFinal(plainText);
//为了方便传输我们可以将byte数组转化为base64的编码
String str = base64Enc(enBytes );
复制代码
下面是解密过程,跟加密过程类似:
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
//先将转为base64编码的加密后的数据转化为byte数组
byte[] enBytes = base64Dec(str);
//解密称为byte数组,应该为字符串数组最后转化为字符串
byte[] deBytes = cipher.doFinal(enBytes);
String strdecoded = new String(deBytes);
复制代码
测试结果如下,能够正常加密和解密
因为每次生成密钥需要的时间较长,所以密钥经过base64进行编码按照字符串保存了,上面的Android程序中的公钥和私钥转化后的字符串如下:
String strpublicKey =
"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCkh0aKknIsmF838HITg8rdA0I+HwS1huM3FGC/rJC0L0UC/DfNp9tYqNgxAoG4WgG+zNtSz2CxghfM8UaUP8eslQRuJHojuZxgy9MLC37Dm4VQaiXALoYdMU3f2593l61Ads3YHHToA4izYprm5Ng3q83QqJoQsopxysRpN274BwIDAQAB";
String strprivateKey =
"MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKSHRoqSciyYXzfwchODyt0DQj4fBLWG4zcUYL+skLQvRQL8N82n21io2DECgbhaAb7M21LPYLGCF8zxRpQ/x6yVBG4keiO5nGDL0wsLfsObhVBqJcAuhh0xTd/bn3eXrUB2zdgcdOgDiLNimubk2DerzdComhCyinHKxGk3bvgHAgMBAAECgYAbnNR69z8QOvZoFgOfQNQwKZbZhC0vJhdGLDZclOKoSvKjIJ9g9ZX7mELIXupUfU6jrg/1IvbQc8v4ylmVEes5x0pSzsbhI3iuH7m5PNLXChqzAN4K1uC6qGNy9WL3lDTQJ2LV57/1S7iDLtWCfv/aseOzStUL9Znv19W6lX6YSQJBAOkW9A5niW9X0LxxbcMw+xwqDvfDv2nZWmCLqT56W+rjrUEP62fqRX2KqP+zwtUHOYwvaiQSh35TyQ+m1e+QdbMCQQC0syvPgrg2oMl+MkYy0cE2uMV+vZ6evzSaeq6BosUQsnpe/DOKTQZ5GkB+BnYMFZFF5YwkBifsXdIApb8mC/JdAj91dBuHJqUadiW4z29/7C6dApSIRRsvO1dPTxD5aq7mrdOf9WWp92MM39JJB0wmDH3zJfFWPAAKqC2otWkYTrMCQQCZ2Z8oi9y6LkXAG5/nLu354HHOijXeZV+tU1z25RYyNDO6YbKkQxaKz44vfuLNQSOyRlH+bftZ5Tui73wDMdLFAkEArVdICaxILdndxnPB/KSUFNPIoupBvjz+WhoyuXiujs2KKtojLY5DMa/LkAcW2Akr9ZwqkPVeuDcDbVQrEEyfdg==";
复制代码
根据以上的编码,可以放到其他的平台和语言中去,进行解码后得到对应的公钥和私钥,要发送消息只需要得到公钥即可,要解密消息得到私钥即可。此外,如果两个人互相发消息,需要设置两组不同的公钥和私钥,同一组公钥和私钥不能放在同一个设备中。
base64decode(key)编码是一个自定义的函数,大家完全可以自己写,我就不列出了。以上代码是我研究在java中进行加密与解密的方法,后来测试与c#通信有问题,因为c#的公钥和私钥与java的组成方式不同,需要用函数转换。自己又不太清楚如何转换,后使用一些开源的类,稍加修改,便可以与c#和java服务器互通了。附件中的公钥和私钥是c#中的公钥和私钥,大家也可以通过RSAHelper里的函数转化成自己需要的java的公钥私钥,或者可以用函数自己生成。具体不多讲,我在RSAHelper.java中的api写的很明白,若不明白的请留言。详细代码见附件:
RSATest.rar (2.1
MB, 下载次数: 81)
另外,附上自己研究c#及Android使用RSA加密解密算法的文档:
20130823(c#中生成rsa密钥和加密和解密的方法以及java中的密钥与c#密钥互转的方法).do.doc (24.5
KB, 下载次数: 8)
//设置使用何种加密算法
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
// 密钥位数
keyPairGen.initialize(1024);
// 密钥对
KeyPair keyPair = keyPairGen.generateKeyPair();
// 公钥
PublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
// 私钥
PrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
复制代码
以上api需要引入以下的包
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
复制代码
为了公钥跟私钥可以传输和保存,因此可以设置为将他们转化成base64的编码,用到以下方法:
/****************************************
* 函数说明:getKeyString 根据key得到64位加密字符串
*
* @param key 密钥
* @throws Exception
* @return String 加密后的字符串
* @author 王洪贺 2013-8-21
***************************************/
public static String getKeyString(Key key) throws Exception
{
byte[] keyBytes = key.getEncoded();
String s = base64Enc(keyBytes);
return s;
}
复制代码
但加密跟解密的时候需要将base64位的编码转化为key的对象,所以用到以下两个方法:
/****************************************
* 函数说明:getPublicKey 取得公钥
*
* @param key 公钥字符串
* @throws Exception
* @return PublicKey 返回公钥
* @author 王洪贺 2013-8-21
***************************************/
public static PublicKey getPublicKey(String key) throws Exception
{
byte[] keyBytes;
keyBytes = base64Dec(key);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(keySpec);
return publicKey;
}
/****************************************
* 函数说明:getPrivateKey 取得私钥
*
* @param key 私钥字符串
* @throws Exception
* @return PrivateKey 返回私钥
* @author 王洪贺 2013-8-21
***************************************/
public static PrivateKey getPrivateKey(String key) throws Exception
{
byte[] keyBytes;
keyBytes = base64Dec(key);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
return privateKey;
}
复制代码
下面就是加密过程,很简单:
// 实例化加解密类
Cipher cipher = Cipher.getInstance("RSA");
// 明文
byte[] plainText = "明文".getBytes();
// 加密
cipher.init(Cipher.ENCRYPT_MODE, publicKe);
//将明文转化为根据公钥加密的密文,为byte数组格式
byte[] enBytes = cipher.doFinal(plainText);
//为了方便传输我们可以将byte数组转化为base64的编码
String str = base64Enc(enBytes );
复制代码
下面是解密过程,跟加密过程类似:
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
//先将转为base64编码的加密后的数据转化为byte数组
byte[] enBytes = base64Dec(str);
//解密称为byte数组,应该为字符串数组最后转化为字符串
byte[] deBytes = cipher.doFinal(enBytes);
String strdecoded = new String(deBytes);
复制代码
测试结果如下,能够正常加密和解密
因为每次生成密钥需要的时间较长,所以密钥经过base64进行编码按照字符串保存了,上面的Android程序中的公钥和私钥转化后的字符串如下:
String strpublicKey =
"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCkh0aKknIsmF838HITg8rdA0I+HwS1huM3FGC/rJC0L0UC/DfNp9tYqNgxAoG4WgG+zNtSz2CxghfM8UaUP8eslQRuJHojuZxgy9MLC37Dm4VQaiXALoYdMU3f2593l61Ads3YHHToA4izYprm5Ng3q83QqJoQsopxysRpN274BwIDAQAB";
String strprivateKey =
"MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKSHRoqSciyYXzfwchODyt0DQj4fBLWG4zcUYL+skLQvRQL8N82n21io2DECgbhaAb7M21LPYLGCF8zxRpQ/x6yVBG4keiO5nGDL0wsLfsObhVBqJcAuhh0xTd/bn3eXrUB2zdgcdOgDiLNimubk2DerzdComhCyinHKxGk3bvgHAgMBAAECgYAbnNR69z8QOvZoFgOfQNQwKZbZhC0vJhdGLDZclOKoSvKjIJ9g9ZX7mELIXupUfU6jrg/1IvbQc8v4ylmVEes5x0pSzsbhI3iuH7m5PNLXChqzAN4K1uC6qGNy9WL3lDTQJ2LV57/1S7iDLtWCfv/aseOzStUL9Znv19W6lX6YSQJBAOkW9A5niW9X0LxxbcMw+xwqDvfDv2nZWmCLqT56W+rjrUEP62fqRX2KqP+zwtUHOYwvaiQSh35TyQ+m1e+QdbMCQQC0syvPgrg2oMl+MkYy0cE2uMV+vZ6evzSaeq6BosUQsnpe/DOKTQZ5GkB+BnYMFZFF5YwkBifsXdIApb8mC/JdAj91dBuHJqUadiW4z29/7C6dApSIRRsvO1dPTxD5aq7mrdOf9WWp92MM39JJB0wmDH3zJfFWPAAKqC2otWkYTrMCQQCZ2Z8oi9y6LkXAG5/nLu354HHOijXeZV+tU1z25RYyNDO6YbKkQxaKz44vfuLNQSOyRlH+bftZ5Tui73wDMdLFAkEArVdICaxILdndxnPB/KSUFNPIoupBvjz+WhoyuXiujs2KKtojLY5DMa/LkAcW2Akr9ZwqkPVeuDcDbVQrEEyfdg==";
复制代码
根据以上的编码,可以放到其他的平台和语言中去,进行解码后得到对应的公钥和私钥,要发送消息只需要得到公钥即可,要解密消息得到私钥即可。此外,如果两个人互相发消息,需要设置两组不同的公钥和私钥,同一组公钥和私钥不能放在同一个设备中。
base64decode(key)编码是一个自定义的函数,大家完全可以自己写,我就不列出了。以上代码是我研究在java中进行加密与解密的方法,后来测试与c#通信有问题,因为c#的公钥和私钥与java的组成方式不同,需要用函数转换。自己又不太清楚如何转换,后使用一些开源的类,稍加修改,便可以与c#和java服务器互通了。附件中的公钥和私钥是c#中的公钥和私钥,大家也可以通过RSAHelper里的函数转化成自己需要的java的公钥私钥,或者可以用函数自己生成。具体不多讲,我在RSAHelper.java中的api写的很明白,若不明白的请留言。详细代码见附件:
本帖隐藏的内容
RSATest.rar (2.1
MB, 下载次数: 81)
另外,附上自己研究c#及Android使用RSA加密解密算法的文档:
20130823(c#中生成rsa密钥和加密和解密的方法以及java中的密钥与c#密钥互转的方法).do.doc (24.5
KB, 下载次数: 8)
相关文章推荐
- C# 与JAVA 的RSA 加密解密交互,互通,C#使用BouncyCastle来实现私钥加密,公钥解密的方法
- 项目开发中的一些注意事项以及技巧总结 基于Repository模式设计项目架构—你可以参考的项目架构设计 Asp.Net Core中使用RSA加密 EF Core中的多对多映射如何实现? asp.net core下的如何给网站做安全设置 获取服务端https证书 Js异常捕获
- C# 与 Java Rsa加密与解密互通
- RSA和AES在c#服务端和android客户端之间的加密解密
- Android平台和java平台 DES、3DES、RSA加密解密互通程序及其不能互通的原因
- android开发 文件数据的AES-128方式加密解密
- C#开发中常用加密解密方法解析
- RSA客户端js加密服务器C#解密(含源码)
- Android RSA加密解密算法解析
- C#开发中常用加密解密方法解析
- Android 3DES加密解密(JAVA和C#)
- C#中RSA加密解密和签名与验证的实现
- C# 加密–RSA前端与后台的加密&解密
- C# Java间进行RSA加密解密交互(三)
- Android IOS WebRTC 音视频开发总结(六二)-- 大数据解密国外实时通讯行业开发现状
- PHP开发接口使用RSA进行加密解密方法
- C# Java间进行RSA加密解密交互
- Android RSA加密解密
- C#开发中常用加密解密方法解析