java、android、ios、js数据传递加密算法之AES加密
2017-09-12 10:40
1961 查看
场景描述
我们在做项目的时候,写接口经常会遇到这样的情况,就是和app端、web端交互的时候传输数据需要进行加密,不能用明文操作。数据传输加密最关键的就是前后端传输的数据最终能被正确的解密出来,今天就来讲讲使用AES加密传输的时候前后端使用的代码。解决方案
首先来看一下后端java的AES加解密工具类// 注意,为了能与 iOS 统一,这里的 key 不可以使用 KeyGenerator、SecureRandom、SecretKey 生成
/** * <p> * 参数加密解密工具,不要和DESEncrypt弄混了 * </p> * * @author ZhaoHang * @date 2017-09-1 11:55 */ public class AESUtils { public static final Logger LOGGER = LoggerFactory.getLogger(AESUtils.class); private static final String AES = "AES"; private static final String CRYPT_KEY = "y2W89L6BkRAFljhN"; private static final String IV_STRING = "dMitHORyqbeYVE0o"; /** * 加密 * * @param content 加密内容 * @return 密文 * @throws Exception e */ public static String encrypt(String content) { byte[] encryptedBytes = new byte[0]; try { byte[] byteContent = content.getBytes("UTF-8"); // 注意,为了能与 iOS 统一 // 这里的 key 不可以使用 KeyGenerator、SecureRandom、SecretKey 生成 byte[] enCodeFormat = CRYPT_KEY.getBytes(); SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, AES); byte[] initParam = IV_STRING.getBytes(); IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam); // 指定加密的算法、工作模式和填充方式 Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec); encryptedBytes = cipher.doFinal(byteContent); // 同样对加密后数据进行 base64 编码 } catch (IOException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException e) { LOGGER.error("AES encrypt Exception,content = {},Exception = {}", content, e.getStackTrace()); } return new BASE64Encoder().encode(encryptedBytes); } /** * 解密 * * @param content 密文 * @return 明文 * @throws Exception e */ public static String decrypt(String content) { // base64 解码 try { byte[] encryptedBytes = new BASE64Decoder().decodeBuffer(content); byte[] enCodeFormat = CRYPT_KEY.getBytes(); SecretKeySpec secretKey = new SecretKeySpec(enCodeFormat, AES); byte[] initParam = IV_STRING.getBytes(); IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec); byte[] result = cipher.doFinal(encryptedBytes); return new String(result, "UTF-8"); } catch (IOException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException e) { LOGGER.error("AES decrypt Exception,content = {},Exception = {}", content, e.getStackTrace()); } return null; } }
android端使用同上与后端java一致
ios端的代码如下
//先定义一个初始向量的值。 NSString *const kInitVector = @"dMitHORyqbeYVE0o"; NSString *const key= @"y2W89L6BkRAFljhN"; //确定密钥长度,这里选择 AES-128。 size_t const kKeySize = kCCKeySizeAES128; /** AES加密方法 @param content 需要加密的字符串 @param key key @return 加密后的字符串 */ + (NSString *)encryptAES:(NSString *)content{ NSData *contentData = [content dataUsingEncoding:NSUTF8StringEncoding]; NSUInteger dataLength = contentData.length; // 为结束符'\\0' +1 char keyPtr[kKeySize + 1]; memset(keyPtr, 0, sizeof(keyPtr)); [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; // 密文长度 <= 明文长度 + BlockSize size_t encryptSize = dataLength + kCCBlockSizeAES128; void *encryptedBytes = malloc(encryptSize); size_t actualOutSize = 0; NSData *initVector = [kInitVector dataUsingEncoding:NSUTF8StringEncoding]; CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES, kCCOptionPKCS7Padding, // 系统默认使用 CBC,然后指明使用 PKCS7Padding keyPtr, kKeySize, initVector.bytes, contentData.bytes, dataLength, encryptedBytes, encryptSize, &actualOutSize); if (cryptStatus == kCCSuccess) { // 对加密后的数据进行 base64 编码 return [[NSData dataWithBytesNoCopy:encryptedBytes length:actualOutSize] base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed]; } free(encryptedBytes); return nil; } /** AES解密方法 @param content 需要解密的字符串 @param key key @return 解密后的字符串 */ + (NSString *)decryptAES:(NSString *)content{ // 把 base64 String 转换成 Data NSData *contentData = [[NSData alloc] initWithBase64EncodedString:content options:NSDataBase64DecodingIgnoreUnknownCharacters]; NSUInteger dataLength = contentData.length; char keyPtr[kKeySize + 1]; memset(keyPtr, 0, sizeof(keyPtr)); [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; size_t decryptSize = dataLength + kCCBlockSizeAES128; void *decryptedBytes = malloc(decryptSize); size_t actualOutSize = 0; NSData *initVector = [kInitVector dataUsingEncoding:NSUTF8StringEncoding]; CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES, kCCOptionPKCS7Padding, keyPtr, kKeySize, initVector.bytes, contentData.bytes, dataLength, decryptedBytes, decryptSize, &actualOutSize); if (cryptStatus == kCCSuccess) { return [[NSString alloc] initWithData:[NSData dataWithBytesNoCopy:decryptedBytes length:actualOutSize] encoding:NSUTF8StringEncoding]; } free(decryptedBytes); return nil; }
接下来是js的代码,js中aes加密需要用到 CryptoJS工具包
下载地址http://download.csdn.net/download/gao36951/9974349
<script type="text/javascript" src="./CryptoJS/crypto-js.js"></script> <script> //直接上代码 var key = CryptoJS.enc.Utf8.parse('y2W89L6BkRAFljhN'); var iv = CryptoJS.enc.Utf8.parse('dMitHORyqbeYVE0o'); var source = '要加密的字符串'; var password=CryptoJS.enc.Utf8.parse(source); console.log("原始字符串:"+source); console.log("utf8处理后:"+password); var encrypted = CryptoJS.AES.encrypt(password, key, { iv: iv,mode:CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7}); //CryptoJS.pad.Pkcs7 var decrypted = CryptoJS.AES.decrypt(encrypted, key, { iv: iv,mode:CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7}); //CryptoJS.pad.Pkcs7 console.log("加密后base64:"+encrypted); var encryptedStr=encrypted.ciphertext.toString(); console.log("加密后16进制:"+encryptedStr); console.log("解密后utf8:"+decrypted); console.log("解密后原始字符串:"+decrypted.toString(CryptoJS.enc.Utf8)); </script>
js测试截图
使用js加密的结果在java中解密如下:
ios的同理,有兴趣的童鞋可以亲测一下,这些都是项目中实际亲测的希望有用~
相关文章推荐
- 数据传输加密:非对称加密算法RSA+对称算法AES(适用于java,android和Web)
- [置顶] 数据传输加密——非对称加密算法RSA+对称算法AES(适用于java,android和Web)
- Java、Android、ios、js数据传递AES加密算法
- ios、Android、java通用AES加密方式
- Android使用webview控件加载本地html,通过Js与后台Java实现数据的传递
- AES加密解密,iOS,Android,Java,.Net通用
- iOS,Android服务器间通用的Base64加密解密传递数据
- JS传递数据给IOS Android
- AES三端加密解密 – iOS与Android,JS的同步实现
- JAVA android IOS AES通用加密
- Android-Ios-Php-Java AES加密解密
- java、js之间使用AES加密通信数据
- 【程序48】 TestCode.java 题目:某个公司采用公用电话传递数据,数据是四位的整数,在传递过程中是加密的,加密规则如下 //:每位数字 都加上5,然后用和除以10的余数代替该数字,再将
- Android 使用JNI实现Java与C之间传递数据
- Android使用JNI实现Java与C之间传递数据
- java和android及IOS对接RSA加密经验
- Android初学------java AES 加密 解密
- AES在Android、JAVA端正常加密解密
- 关于Des加密(Android与ios 与后台java服务器之间的加密解密
- Android使用JNI实现Java与C之间传递数据 .