在项目工程中,有时候需要对网络传输的数据进行加密。有多种方式,本文使用3DES与RSA加密结合使用。
基本流程如下:
1、假设客户端获取了用户名与密码,需要传给服务器;本文使用RSA工具类生成公钥月私钥,公钥用于客户端加密,私钥用于服务端解密。
String content="用户名+密码";
2、自定义3DES加密密钥和向量:
// 密钥 ,至少24位
private final static String secretKey = "123456781234567812345678aaa";
// 向量 8位
private final static String iv = "3213abcd";
3、使用3DES对内容加密获取加密后的字符串
4、使用RSA对密钥和向量用公钥加密
5、服务器接收数据,用RSA私钥解密,获取密钥和向量,再使用3DES解密获取内容。
原理是:使用3DES对长内容加密,使用RSA对3DES使用的密钥加密,这样加密速度快,效率高。
注意点:
加密解密过程中对byte[] 与String 之间的转化,不能直接使用String。getBytes的方式,必须用特定的工具。这里本文使用的是系统自带的Base64中的方法。也可以使用sun中的BASE64Encoder方式,但是这种需要下载专门的jar。
RSA加密速度较慢,所以我们不对长内容加密。假设有变态的非要对长长的内容加密,本文在下面的RSA工具类中也封装了相关的方法,partSplit分段加密和解密。
具体代码如下:
3DES加密解密方法及常量:
// 密钥 ,至少24位 private final static String secretKey = "123456781234567812345678aaa"; // 向量 8位 private final static String iv = "3213abcd"; // 加解密统一使用的编码方式 private final static String encoding = "utf-8"; /** * DESTool加密 * * @param plainText 普通文本 * @return * @throws Exception */ public static String encode(String plainText) throws Exception { Key deskey = null; DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes()); SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("DESede"); deskey = keyfactory.generateSecret(spec); Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding"); IvParameterSpec ips = new IvParameterSpec(iv.getBytes()); cipher.init(Cipher.ENCRYPT_MODE, deskey, ips); byte[] encryptData = cipher.doFinal(plainText.getBytes(encoding)); return Base64.encodeToString(encryptData,Base64.DEFAULT); } /** * DESTool解密 * * @param encryptText 加密文本 * @return * @throws Exception */ public static String decode(String encryptText, String secretKey, String iv) throws Exception { Key deskey = null; DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes()); SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede"); deskey = keyfactory.generateSecret(spec); Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding"); IvParameterSpec ips = new IvParameterSpec(iv.getBytes()); cipher.init(Cipher.DECRYPT_MODE, deskey, ips); byte[] decryptData = cipher.doFinal(Base64.decode(encryptText,Base64.DEFAULT)); return new String(decryptData, encoding); }主要测试代码:
b31.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { String content="用户名+密码"; Log.e("b31", "加密前content数据 ---->" + content); String s1 = encode(content); Log.e("b31", "DES加密后content数据 ---->" + s1); KeyPair keyPair = RSAUtil.generateRSAKeyPair(RSAUtil.DEFAULT_KEY_SIZE); // 公钥 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // 私钥 RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();