赞
踩
最近开发 用到数据加密 研究后要用RSA和AES对称加密工具
以前没搞过 记录一下心酸过程
客户端和服务端的加密代码是不同的 即使都是java语言 只有一些模式和参数需要同步设置
比如字节码和加密模式
package com.mob.common.utils; import android.util.Base64; import java.io.UnsupportedEncodingException; import java.security.InvalidKeyException; import java.security.Key; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; /** * RSA加密工具 */ public class RSAUtils { //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" private static String sTransform = "RSA/NONE/PKCS1Padding"; //进行Base64转码时的flag设置,默认为Base64.DEFAULT private static int sBase64Mode = Base64.DEFAULT; //初始化方法,设置参数 public static void init(String transform, int base64Mode) { sTransform = transform; sBase64Mode = base64Mode; } /* 产生密钥对 @param keyLength 密钥长度,小于1024长度的密钥已经被证实是不安全的,通常设置为1024或者2048,建议2048 */ public static KeyPair generateRSAKeyPair(int keyLength) { KeyPair keyPair = null; try { KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); //设置密钥长度 keyPairGenerator.initialize(keyLength); //产生密钥对 keyPair = keyPairGenerator.generateKeyPair(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return keyPair; } /* 加密或解密数据的通用方法 @param srcData 待处理的数据 @param key 公钥或者私钥 @param mode 指定是加密还是解密,值为Cipher.ENCRYPT_MODE或者Cipher.DECRYPT_MODE */ private static byte[] processData(byte[] srcData, Key key, int mode) { //用来保存处理结果 byte[] resultBytes = null; try { //获取Cipher实例 Cipher cipher = Cipher.getInstance(sTransform); //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 cipher.init(mode, key); //处理数据 resultBytes = cipher.doFinal(srcData); } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { e.printStackTrace(); } return resultBytes; } /* 使用公钥加密数据,结果用Base64转码 */ public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); if (resultBytes != null && resultBytes.length > 0) { return Base64.encodeToString(resultBytes, sBase64Mode); } return ""; } /* 使用私钥解密,返回解码数据 */ public static byte[] decryptDataByPrivate(String encryptedData, PrivateKey privateKey) { byte[] bytes = Base64.decode(encryptedData, sBase64Mode); return processData(bytes, privateKey, Cipher.DECRYPT_MODE); } /* 使用私钥进行解密,解密数据转换为字符串,使用utf-8编码格式 */ public static String decryptedToStrByPrivate(String encryptedData, PrivateKey privateKey) { return new String(decryptDataByPrivate(encryptedData, privateKey)); } /* 使用私钥解密,解密数据转换为字符串,并指定字符集 */ public static String decryptedToStrByPrivate(String encryptedData, PrivateKey privateKey, String charset) { try { return new String(decryptDataByPrivate(encryptedData, privateKey), charset); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return null; } /* 使用私钥加密,结果用Base64转码 */ public static String encryptDataByPrivateKey(byte[] srcData, PrivateKey privateKey) { byte[] resultBytes = processData(srcData, privateKey, Cipher.ENCRYPT_MODE); return Base64.encodeToString(resultBytes, sBase64Mode); } /* 使用公钥解密,返回解密数据 */ public static byte[] decryptDataByPublicKey(String encryptedData, PublicKey publicKey) { byte[] bytes = Base64.decode(encryptedData, sBase64Mode); return processData(bytes, publicKey, Cipher.DECRYPT_MODE); } /* 使用公钥解密,结果转换为字符串,使用默认字符集utf-8 */ public static String decryptedToStrByPublicKey(String encryptedData, PublicKey publicKey) { return new String(decryptDataByPublicKey(encryptedData, publicKey)); } /* 使用公钥解密,结果转换为字符串,使用指定字符集 */ public static String decryptedToStrByPublicKey(String encryptedData, PublicKey publicKey, String charset) { try { return new String(decryptDataByPublicKey(encryptedData, publicKey), charset); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return null; } /* 将字符串形式的公钥转换为公钥对象 */ public static PublicKey keyStrToPublicKey(String publicKeyStr) { PublicKey publicKey = null; byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); try { KeyFactory keyFactory = KeyFactory.getInstance("RSA"); publicKey = keyFactory.generatePublic(keySpec); } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { e.printStackTrace(); } return publicKey; } /* 将字符串形式的私钥,转换为私钥对象 */ public static PrivateKey keyStrToPrivate(String privateKeyStr) { PrivateKey privateKey = null; byte[] keyBytes = Base64.decode(privateKeyStr, sBase64Mode); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); try { KeyFactory keyFactory = KeyFactory.getInstance("RSA"); privateKey = keyFactory.generatePrivate(keySpec); } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { e.printStackTrace(); } return privateKey; } }
package com.mob.common.utils; import android.util.Base64; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; /** * AES加密工具 */ public class AESUtils { /** * 加密算法 */ private static final String KEY_ALGORITHM = "AES"; /** * AES 的 密钥长度,32 字节,范围:16 - 32 字节 */ public static final int SECRET_KEY_LENGTH = 16; /** * 字符编码 */ private static final Charset CHARSET_UTF8 = StandardCharsets.UTF_8; /** * 秘钥长度不足 16 个字节时,默认填充位数 */ private static final String DEFAULT_VALUE = "0"; /** * 加解密算法/工作模式/填充方式 */ private static final String CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding"; /** * AES 加密 * * @param data 待加密内容 * @param secretKey 加密密码,长度:16 或 32 个字符 * @return 返回Base64转码后的加密数据 */ public static String encrypt(String data, String secretKey) { try { //创建密码器 Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); //初始化为加密密码器 cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(secretKey)); byte[] encryptByte = cipher.doFinal(data.getBytes(CHARSET_UTF8)); // 将加密以后的数据进行 Base64 编码 return base64Encode(encryptByte); } catch (Exception e) { handleException(e); } return null; } /** * AES 解密 * * @param base64Data 加密的密文 Base64 字符串 * @param secretKey 解密的密钥,长度:16 或 32 个字符 */ public static String decrypt(String base64Data, String secretKey) { try { byte[] data = base64Decode(base64Data); Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); //设置为解密模式 cipher.init(Cipher.DECRYPT_MODE, getSecretKey(secretKey)); //执行解密操作 byte[] result = cipher.doFinal(data); return new String(result, CHARSET_UTF8); } catch (Exception e) { handleException(e); } return null; } /** * 使用密码获取 AES 秘钥 */ public static SecretKeySpec getSecretKey(String secretKey) { secretKey = toMakeKey(secretKey, SECRET_KEY_LENGTH, DEFAULT_VALUE); return new SecretKeySpec(secretKey.getBytes(CHARSET_UTF8), KEY_ALGORITHM); } /** * 如果 AES 的密钥小于 {@code length} 的长度,就对秘钥进行补位,保证秘钥安全。 * * @param secretKey 密钥 key * @param length 密钥应有的长度 * @param text 默认补的文本 * @return 密钥 */ private static String toMakeKey(String secretKey, int length, String text) { // 获取密钥长度 int strLen = secretKey.length(); // 判断长度是否小于应有的长度 if (strLen < length) { // 补全位数 StringBuilder builder = new StringBuilder(); // 将key添加至builder中 builder.append(secretKey); // 遍历添加默认文本 for (int i = 0; i < length - strLen; i++) { builder.append(text); } // 赋值 secretKey = builder.toString(); } return secretKey; } /** * 将 Base64 字符串 解码成 字节数组 */ public static byte[] base64Decode(String data) { return Base64.decode(data, Base64.NO_WRAP); } /** * 将 字节数组 转换成 Base64 编码 */ public static String base64Encode(byte[] data) { return Base64.encodeToString(data, Base64.NO_WRAP); } /** * 处理异常 */ private static void handleException(Exception e) { e.printStackTrace(); } }
//字符串公钥 public static final String PUBLIC_KEY_STR = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHhR8P0HdnoXXvgeH2DIIxHWrI\n" + "bfH4+rr3sqJ5z/mkBcYu7+n2f74CZABZGXyNyVMZgGB8giPKijBxjZuMAevqHxuR\n" + "Yi22DxyOnP3kQXQVaHv9XukPpZXpDsxj6jb1ngy8rRrw2Zb1ofGLDicM2IVB9Ma8\n" + "G8wdIPu10qrVytYsLwIDAQAB"; //字符串密钥 public static final String PRIVATE_KEY_STR = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJK3E8oqdY/AfV71/Dx+RaYhTV52hdkPgPfTAAyvH5doQvHG0WrgfGoona410P45/6NJ8w02BTWaU3wOwBR082mnmNk18edwb2vi+2RrYhO4micTfNRq5jFwapvh+FqYCJLe1VDWNwQtdLaf7b7OrqG9sZ2vMDyw8bujhdRkOvenAgMBAAECgYAZspV1yKAU0Ltk4aMPmXJrmdOqYwoorc2CGuQcVKQs6ecn4BIYLT+9fGW5+NUlYlVDbZVzz+1zqRdMWG0OaDmmFoyqzZ0te+vwekzdniCBkGK+1i9nSyR6ix9zdmXLxPlh4qxYZ0kiBwPtCKsb1RddlmBEneMGiCtLxe62b0TmQQJBAP1UGTiMOPi+X4i2/PTfBC99fKv/6trXmcczgdJmdS9ThfsO3y9sQbIdwXaR/z6eBKCLb9QYYrNSrFeWUZHj9KECQQCUQyifZXqGYP+5fMMZsKE2RuZf8dQ1OknK73S+EvlaDTvmd/DNGB3v9Kxmh0rJgmdUA6gK9drEVRYuxs1rvr9HAkBHCfBQpTHMv0X3BqmE2Y1I6/2sFgX7/H3JGK6NG+I8tUVbE96OY+NAWYvI/kP/gTx28OMZLQVwl/xwS1zwdmZBAkAn08ak0vjQAlyPslEipI0Z7H/URD0yMz9BcYPVz3kGVMnDhnK8VX8tR3fMbwmLCinBqt3IW/Txir3TwPnLuMjfAkAcbOPSFt0ebHYdKU9aeoFsBnDycT7GYYLWl4h1bZ+TAWcsnp46s1IJLVPIscwOOlIsxgd2+OX2OOSgxXPlT3RD"; public static final String CONTENT = "TI3b7oglaExMRLZ+2XZrNBW+ExMmbPk+Js9SAKt4xuf1UfGrYIYInQkMUPIt1D4QnOyvnblUfle54B9/IAMNefban5IRBmh4dPKd/c7yqVIGPzWeVujfWJZjFw8owNX0gwNcixb7fbIDk16ZRpZHoqtHLsCzMLljCMYHqHhkwY4="; /** * Rsa测试代码 */ String s = RSAUtils.decryptedToStrByPrivate(CONTENT, RSAUtils.keyStrToPrivate(PRIVATE_KEY_STR)); Log.e("RSA解密:", s); //获取公钥 PublicKey publicKey = RSAUtils.keyStrToPublicKey(PUBLIC_KEY_STR); //获取私钥 PrivateKey privateKey = RSAUtils.keyStrToPrivate(PRIVATE_KEY_STR); //需要加密的数据 String clearText01 = "123"; //公钥加密结果 String publicEncryptedResult = RSAUtils.encryptDataByPublicKey(clearText01.getBytes(), publicKey); //私钥解密结果 String privateDecryptedResult = RSAUtils.decryptedToStrByPrivate(publicEncryptedResult, privateKey); Logger.d("公钥加密,私钥解密测试:\n" + "原文:\n" + clearText01 + "\n" + "公钥加密结果:\n" + publicEncryptedResult + "\n" + "私钥解密结果:\n" + privateDecryptedResult ); //需要加密的数据 String clearText02 = "456"; //私钥加密结果 String privateEncryptedResult = RSAUtils.encryptDataByPrivateKey(clearText02.getBytes(), privateKey); //公钥解密结果 String publicDecryptedResult = RSAUtils.decryptedToStrByPublicKey(privateEncryptedResult, publicKey); Logger.d("私钥加密,公钥解密测试:\n" + "原文:\n" + clearText02 + "\n" + "私钥加密结果:\n" + privateEncryptedResult + "\n" + "公钥解密结果:\n" + publicDecryptedResult ); /** * AES测试代码 */ try { String encrypt = AESUtils.decrypt( "jpgg/hUUtntX3D6VAnA7LWw9eGkdfp1WIjtBKnOWOjY=","wyq6hxm1cqmq4w8r"); Log.e("AES-解密:", encrypt); } catch (Exception e) { e.printStackTrace(); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。