安卓、IOS端AEC密钥加密 Java端密钥解密通用实现(16进制表现形式)
由于业务需求,需要实现在客户端对重要信息进行加密,在服务端进行解密。客户端包括IOS和安卓的 服务端位Java。
注意密钥 需要保持一致,可以自己定义 。
安卓端加密代码:
=====================================================================================================================
import android.util.Base64; import java.io.UnsupportedEncodingException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; public class SymmetricEncoder { private static final String IV_STRING = "A-16-Byte-String"; private static final String charset = "UTF-8"; /** * * @param content 要加密的内容 * @param key 16位加密密钥 * @return * @throws Exception */ public static String aesEncryptHexStr(String content, String key) throws Exception { return str2HexStr(aesEncryptString(content,key)); } public static String aesEncryptString(String content, String key) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException { byte[] contentBytes = content.getBytes(charset); byte[] keyBytes = key.getBytes(charset); byte[] encryptedBytes = aesEncryptBytes(contentBytes, keyBytes); return Base64.encodeToString(encryptedBytes, Base64.NO_WRAP); } /** * 字符串转换成十六进制字符串 * @return String 每个Byte之间空格分隔,如: [61 6C 6B] */ public static String str2HexStr(String str) { char[] chars = "0123456789ABCDEF".toCharArray(); StringBuilder sb = new StringBuilder(""); byte[] bs = str.getBytes(); int bit; for (int i = 0; i < bs.length; i++) { bit = (bs[i] & 0x0f0) >> 4; sb.append(chars[bit]); bit = bs[i] & 0x0f; sb.append(chars[bit]); } return sb.toString().trim(); } public static String aesDecryptString(String content, String key) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException { byte[] encryptedBytes = Base64.decode(content.getBytes(), Base64.NO_WRAP); byte[] keyBytes = key.getBytes(charset); byte[] decryptedBytes = aesDecryptBytes(encryptedBytes, keyBytes); return new String(decryptedBytes, charset); } public static byte[] aesEncryptBytes(byte[] contentBytes, byte[] keyBytes) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException { return cipherOperation(contentBytes, keyBytes, Cipher.ENCRYPT_MODE); } public static byte[] aesDecryptBytes(byte[] contentBytes, byte[] keyBytes) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException { return cipherOperation(contentBytes, keyBytes, Cipher.DECRYPT_MODE); } private static byte[] cipherOperation(byte[] contentBytes, byte[] keyBytes, int mode) throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException { SecretKeySpec secretKey = new SecretKeySpec(keyBytes, "AES"); byte[] initParam = IV_STRING.getBytes(charset); IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(mode, secretKey, ivParameterSpec); return cipher.doFinal(contentBytes); } public static void main(String args[]){ try { // 要加密的内容 加密的密钥 SymmetricEncoder.aesEncryptHexStr("xiaoming9999","ABCDEFGHIJKLMNOP"); } catch (Exception e) { e.printStackTrace(); } } }
IOS 端加密:
=====================================================================================================================
// AESCipher.h #import <Foundation/Foundation.h> NSString * aesEncryptString(NSString *content, NSString *key); NSString * aesEncryptHexStr(NSString *content, NSString *key);//16进制表现形式 NSString * aesDecryptString(NSString *content, NSString *key); NSString * hexStringFromString(NSString *string);
NSData * aesEncryptData(NSData *data, NSData *key); NSData * aesDecryptData(NSData *data, NSData *key);
// // AESCipher.m // AESCipher // #import "AESCipher.h" #import <CommonCrypto/CommonCryptor.h> NSString const *kInitVector = @"A-16-Byte-String"; size_t const kKeySize = kCCKeySizeAES128; NSData * cipherOperation(NSData *contentData, NSData *keyData, CCOperation operation) { NSUInteger dataLength = contentData.length; void const *initVectorBytes = [kInitVector dataUsingEncoding:NSUTF8StringEncoding].bytes; void const *contentBytes = contentData.bytes; void const *keyBytes = keyData.bytes; size_t operationSize = dataLength + kCCBlockSizeAES128; void *operationBytes = malloc(operationSize); size_t actualOutSize = 0; CCCryptorStatus cryptStatus = CCCrypt(operation, kCCAlgorithmAES, kCCOptionPKCS7Padding, keyBytes, kKeySize, initVectorBytes, contentBytes, dataLength, operationBytes, operationSize, &actualOutSize); if (cryptStatus == kCCSuccess) { return [NSData dataWithBytesNoCopy:operationBytes length:actualOutSize]; } free(operationBytes); return nil; } NSString * aesEncryptString(NSString *content, NSString *key) { NSData *contentData = [content dataUsingEncoding:NSUTF8StringEncoding]; NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding]; NSData *encrptedData = aesEncryptData(contentData, keyData); return [encrptedData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed]; } NSString * aesEncryptHexStr(NSString *content, NSString *key){ NSString *str=aesDecryptString(content,key); return hexStringFromString(str); } //普通字符串转换为十六进制的。 NSString * hexStringFromString(NSString *string){ NSData *myD = [string dataUsingEncoding:NSUTF8StringEncoding]; Byte *bytes = (Byte *)[myD bytes]; //下面是Byte 转换为16进制。 NSString *hexStr=@""; for(int i=0;i<[myD length];i++) { NSString *newHexStr = [NSString stringWithFormat:@"%x",bytes[i]&0xff];///16进制数 if([newHexStr length]==1) hexStr = [NSString stringWithFormat:@"%@0%@",hexStr,newHexStr]; else hexStr = [NSString stringWithFormat:@"%@%@",hexStr,newHexStr]; } return hexStr; } NSString * aesDecryptString(NSString *content, NSString *key) { NSData *contentData = [[NSData alloc] initWithBase64EncodedString:content options:NSDataBase64DecodingIgnoreUnknownCharacters]; NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding]; NSData *decryptedData = aesDecryptData(contentData, keyData); return [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding]; } NSData * aesEncryptData(NSData *contentData, NSData *keyData) { NSString *hint = [NSString stringWithFormat:@"The key size of AES-%lu should be %lu bytes!", kKeySize * 8, kKeySize]; NSCAssert(keyData.length == kKeySize, hint); return cipherOperation(contentData, keyData, kCCEncrypt); } NSData * aesDecryptData(NSData *contentData, NSData *keyData) { NSString *hint = [NSString stringWithFormat:@"The key size of AES-%lu should be %lu bytes!", kKeySize * 8, kKeySize]; NSCAssert(keyData.length == kKeySize, hint); return cipherOperation(contentData, keyData, kCCDecrypt); }
调用方式:
1、引入#import "AESCipher.h" 文件
2、
NSString *userID = aesEncryptHexStr([NSString stringWithFormat:@"%@;%@",userID,userPassword],@"ABCDEFGHIJKLMNOP");
JAVA服务端解密:
=====================================================================================================================
import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.io.UnsupportedEncodingException; public class SymmetricEncoder { private static final String IV_STRING = "A-16-Byte-String"; private static final String charset = "UTF-8"; public static String aesEncryptString(String content, String key) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException { byte[] contentBytes = content.getBytes(charset); byte[] keyBytes = key.getBytes(charset); byte[] encryptedBytes = aesEncryptBytes(contentBytes, keyBytes); //Encoder encoder = Base64.getEncoder(); return new BASE64Encoder().encode((encryptedBytes)); } public static String aesDecryptString(String content, String key) throws Exception { //Decoder decoder = Base64.getDecoder(); byte[] encryptedBytes = new BASE64Decoder().decodeBuffer(content); byte[] keyBytes = key.getBytes(charset); byte[] decryptedBytes = aesDecryptBytes(encryptedBytes, keyBytes); return new String(decryptedBytes, charset); } public static byte[] aesEncryptBytes(byte[] contentBytes, byte[] keyBytes) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException { return cipherOperation(contentBytes, keyBytes, Cipher.ENCRYPT_MODE); } public static byte[] aesDecryptBytes(byte[] contentBytes, byte[] keyBytes) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException { return cipherOperation(contentBytes, keyBytes, Cipher.DECRYPT_MODE); } private static byte[] cipherOperation(byte[] contentBytes, byte[] keyBytes, int mode) throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException { SecretKeySpec secretKey = new SecretKeySpec(keyBytes, "AES"); byte[] initParam = IV_STRING.getBytes(charset); IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(mode, secretKey, ivParameterSpec); return cipher.doFinal(contentBytes); } /** * 十六进制转换字符串 * @param String str Byte字符串(Byte之间无分隔符 如:[616C6B]) * @return String 对应的字符串 */ public static String hexStr2Str(String hexStr) { String str = "0123456789ABCDEF"; char[] hexs = hexStr.toCharArray(); byte[] bytes = new byte[hexStr.length() / 2]; int n; for (int i = 0; i < bytes.length; i++) { n = str.indexOf(hexs[2 * i]) * 16; n += str.indexOf(hexs[2 * i + 1]); bytes[i] = (byte) (n & 0xff); } return new String(bytes); }public static String aesDecryptHexStr(String aecStr,String key) throws Exception{ return SymmetricEncoder.aesDecryptString(SymmetricEncoder.hexStr2Str(aecStr),key); } public static void main(String args[]){ try { String ss="364453613168592F4E68532F4F75306C7A72585459754F62686E43777475377733363339476278514468773D"; System.out.println(SymmetricEncoder.aesDecryptHexStr(ss, "ABCDEFGHIJKLMNOP")); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }