JAVA android IOS AES通用加密
1、环境:JDK6
2、涉及JAR包:
bcprov-jdk15on-152.jar 下载地址:http://www.bouncycastle.org/latest_releases.html 存在位置项目lib目录下
local_policy.jar、US_export_policy.jar 下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html 当前使用JDK路径下:jrelibsecurity替换源文件
1、JAVA和ANDROID端:
package encrypt.ios; import java.io.UnsupportedEncodingException; import java.security.Key; import java.security.Security; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; public class AES256Encryption{ /** * 密钥算法 * java6支持56位密钥,bouncycastle支持64位 * */ public static final String KEY_ALGORITHM="AES"; /** * 加密/解密算法/工作模式/填充方式 * * JAVA6 支持PKCS5PADDING填充方式 * Bouncy castle支持PKCS7Padding填充方式 * */ public static final String CIPHER_ALGORITHM="AES/ECB/PKCS7Padding"; /** * * 生成密钥,java6只支持56位密钥,bouncycastle支持64位密钥 * @return byte[] 二进制密钥 * */ public static byte[] initkey() throws Exception{ //实例化密钥生成器 Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); KeyGenerator kg=KeyGenerator.getInstance(KEY_ALGORITHM, "BC"); //初始化密钥生成器,AES要求密钥长度为128位、192位、256位 kg.init(256); // kg.init(128); // //生成密钥 SecretKey secretKey=kg.generateKey(); //获取二进制密钥编码形式 return secretKey.getEncoded(); /* //为了便于测试,这里我把key写死了,如果大家需要自动生成,可用上面注释掉的代码 return new byte[] { 0x08, 0x08, 0x04, 0x0b, 0x02, 0x0f, 0x0b, 0x0c, 0x01, 0x03, 0x09, 0x07, 0x0c, 0x03, 0x07, 0x0a, 0x04, 0x0f, 0x06, 0x0f, 0x0e, 0x09, 0x05, 0x01, 0x0a, 0x0a, 0x01, 0x09, 0x06, 0x07, 0x09, 0x0d };*/ } /** * 转换密钥 * @param key 二进制密钥 * @return Key 密钥 * */ public static Key toKey(byte[] key) throws Exception{ //实例化DES密钥 //生成密钥 SecretKey secretKey=new SecretKeySpec(key,KEY_ALGORITHM); return secretKey; } /** * 加密数据 * @param data 待加密数据 * @param key 密钥 * @return byte[] 加密后的数据 * */ public static byte[] encrypt(byte[] data,byte[] key) throws Exception{ //还原密钥 Key k=toKey(key); /** * 实例化 * 使用 PKCS7PADDING 填充方式,按如下方式实现,就是调用bouncycastle组件实现 * Cipher.getInstance(CIPHER_ALGORITHM,"BC") */ Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); Cipher cipher=Cipher.getInstance(CIPHER_ALGORITHM, "BC"); //初始化,设置为加密模式 cipher.init(Cipher.ENCRYPT_MODE, k); //执行操作 return cipher.doFinal(data); } /** * 加密数据 * @param data 待加密数据 * @param key 密钥 * @return byte[] 加密后的数据 * */ public static byte[] encrypt(byte[] data,String key) throws Exception{ //还原密钥 Key k=toKey((new BASE64Decoder()).decodeBuffer(key)); /** * 实例化 * 使用 PKCS7PADDING 填充方式,按如下方式实现,就是调用bouncycastle组件实现 * Cipher.getInstance(CIPHER_ALGORITHM,"BC") */ Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); Cipher cipher=Cipher.getInstance(CIPHER_ALGORITHM, "BC"); //初始化,设置为加密模式 cipher.init(Cipher.ENCRYPT_MODE, k); //执行操作 return cipher.doFinal(data); } /** * 解密数据 * @param data 待解密数据 * @param key 密钥 * @return byte[] 解密后的数据 * */ public static byte[] decrypt(byte[] data,byte[] key) throws Exception{ //欢迎密钥 Key k =toKey(key); /** * 实例化 * 使用 PKCS7PADDING 填充方式,按如下方式实现,就是调用bouncycastle组件实现 * Cipher.getInstance(CIPHER_ALGORITHM,"BC") */ Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); Cipher cipher=Cipher.getInstance(CIPHER_ALGORITHM, "BC"); //初始化,设置为解密模式 cipher.init(Cipher.DECRYPT_MODE, k); //执行操作 return cipher.doFinal(data); } /** * 解密数据 * @param data 待解密数据 * @param key 密钥 * @return byte[] 解密后的数据 * */ public static byte[] decrypt(byte[] data,String key) throws Exception{ //欢迎密钥 Key k =toKey((new BASE64Decoder()).decodeBuffer(key)); /** * 实例化 * 使用 PKCS7PADDING 填充方式,按如下方式实现,就是调用bouncycastle组件实现 * Cipher.getInstance(CIPHER_ALGORITHM,"BC") */ Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); Cipher cipher=Cipher.getInstance(CIPHER_ALGORITHM, "BC"); //初始化,设置为解密模式 cipher.init(Cipher.DECRYPT_MODE, k); //执行操作 return cipher.doFinal(data); } /** * @param args * @throws UnsupportedEncodingException * @throws Exception */ public static void main(String[] args) throws UnsupportedEncodingException{ String str="AES"; System.out.println("原文:"+str); //初始化密钥 byte[] key; try { key = (new BASE64Decoder()).decodeBuffer("Fum0rCudZw/fvNCXi05o/NGUqNQuZizD/+xK1FarK38=");//AES256Encryption.initkey(); System.out.println("BASE64密钥:" + (new BASE64Encoder()).encodeBuffer(key)); System.out.print(" "); System.out.println("密钥长度:"+key.length); System.out.print(" "); System.out.println("密钥BYTE:"+key.toString()); System.out.print(" "); System.out.print("密钥:"); for(int i = 0;i<key.length;i++){ System.out.printf("%x", key[i]); } System.out.print(" "); //加密数据 byte[] data=AES256Encryption.encrypt(str.getBytes(), key); System.out.print("加密后:"); for(int i = 0;i<data.length;i++){ System.out.printf("%x", data[i]); } System.out.print(" "); String dateBase64 = new BASE64Encoder().encodeBuffer(data ); System.out.println("加密后BSE64:" + new BASE64Encoder().encodeBuffer(data)); //解密数据 data=AES256Encryption.decrypt(new BASE64Decoder().decodeBuffer("V05aWtYB3G+a689gCGe4CWeFgKu1/X2Zmk9XUD6QflxdbQtjExxZe2PAdFqYnB+c/wCj40VW6ycSmG/rTLdkjA=="), key); System.out.println("解密后:"+new String(data)); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
2、IOS端
EncryptAndDecrypt.h文件 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 // // EncryptAndDecrypt.h // AES256EncryptionDemo // // Created by rich sun on 12-12-13. // Copyright (c) 2012年 rich sun. All rights reserved. // #import <Foundation/Foundation.h> @class NSString; @interface NSData (Encryption) - (NSData *)AES256EncryptWithKey:(NSData *)key; //加密 - (NSData *)AES256DecryptWithKey:(NSData *)key; //解密 - (NSString *)newStringInBase64FromData; //追加64编码 + (NSString*)base64encode:(NSString*)str; //同上64编码 @end EncryptAndDecrypt.m文件 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 // // EncryptAndDecrypt.m // AES256EncryptionDemo // // Created by rich sun on 12-12-13. // Copyright (c) 2012年 rich sun. All rights reserved. // #import "EncryptAndDecrypt.h" #import <CommonCrypto/CommonCrypto.h> static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; @implementation NSData (Encryption) - (NSData *)AES256EncryptWithKey:(NSData *)key //加密 { //AES256加密,密钥应该是32位的 const void * keyPtr2 = [key bytes]; char (*keyPtr)[32] = keyPtr2; //对于块加密算法,输出大小总是等于或小于输入大小加上一个块的大小 //所以在下边需要再加上一个块的大小 NSUInteger dataLength = [self length]; size_t bufferSize = dataLength + kCCBlockSizeAES128; void *buffer = malloc(bufferSize); size_t numBytesEncrypted = 0; CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding/*这里就是刚才说到的PKCS7Padding填充了*/ | kCCOptionECBMode, [key bytes], kCCKeySizeAES256, NULL,/* 初始化向量(可选) */ [self bytes], dataLength,/*输入*/ buffer, bufferSize,/* 输出 */ &numBytesEncrypted); if (cryptStatus == kCCSuccess) { return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted]; } free(buffer);//释放buffer return nil; } - (NSData *)AES256DecryptWithKey:(NSData *)key //解密 { //同理,解密中,密钥也是32位的 const void * keyPtr2 = [key bytes]; char (*keyPtr)[32] = keyPtr2; //对于块加密算法,输出大小总是等于或小于输入大小加上一个块的大小 //所以在下边需要再加上一个块的大小 NSUInteger dataLength = [self length]; size_t bufferSize = dataLength + kCCBlockSizeAES128; void *buffer = malloc(bufferSize); size_t numBytesDecrypted = 0; CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding/*这里就是刚才说到的PKCS7Padding填充了*/ | kCCOptionECBMode, keyPtr, kCCKeySizeAES256, NULL,/* 初始化向量(可选) */ [self bytes], dataLength,/* 输入 */ buffer, bufferSize,/* 输出 */ &numBytesDecrypted); if (cryptStatus == kCCSuccess) { return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted]; } free(buffer); return nil; } - (NSString *)newStringInBase64FromData //追加64编码 { NSMutableString *dest = [[NSMutableString alloc] initWithString:@""]; unsigned char * working = (unsigned char *)[self bytes]; int srcLen = [self length]; for (int i=0; i<srcLen; i += 3) { for (int nib=0; nib<4; nib++) { int byt = (nib == 0)?0:nib-1; int ix = (nib+1)*2; if (i+byt >= srcLen) break; unsigned char curr = ((working[i+byt] << (8-ix)) & 0x3F); if (i+nib < srcLen) curr |= ((working[i+nib] >> ix) & 0x3F); [dest appendFormat:@"%c", base64[curr]]; } } return dest; } + (NSString*)base64encode:(NSString*)str { if ([str length] == 0) return @""; const char *source = [str UTF8String]; int strlength = strlen(source); char *characters = malloc(((strlength + 2) / 3) * 4); if (characters == NULL) return nil; NSUInteger length = 0; NSUInteger i = 0; while (i < strlength) { char buffer[3] = {0,0,0}; short bufferLength = 0; while (bufferLength < 3 && i < strlength) buffer[bufferLength++] = source[i++]; characters[length++] = base64[(buffer[0] & 0xFC) >> 2]; characters[length++] = base64[((buffer[0] & 0x03) << 4) | ((buffer[1] & 0xF0) >> 4)]; if (bufferLength > 1) characters[length++] = base64[((buffer[1] & 0x0F) << 2) | ((buffer[2] & 0xC0) >> 6)]; else characters[length++] = "="; if (bufferLength > 2) characters[length++] = base64[buffer[2] & 0x3F]; else characters[length++] = "="; } NSString *g = [[NSString alloc] initWithBytesNoCopy:characters length:length encoding:NSASCIIStringEncoding freeWhenDone:YES]; return g; } @end ViewController.m文件 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 // // ViewController.m // AES256EncryptionDemo // // Created by 孙 裔 on 12-12-13. // Copyright (c) 2012年 rich sun. All rights reserved. // #import "ViewController.h" #import "EncryptAndDecrypt.h" @interface ViewController () @end @implementation ViewController @synthesize plainTextField; - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } //这个函数实现了用户输入完后点击视图背景,关闭键盘 - (IBAction)backgroundTap:(id)sender{ [plainTextField resignFirstResponder]; } - (IBAction)encrypt:(id)sender { NSString *plainText = plainTextField.text;//明文 NSData *plainTextData = [plainText dataUsingEncoding:NSUTF8StringEncoding]; //为了测试,这里先把密钥写死 Byte keyByte[] = {0x08,0x08,0x04,0x0b,0x02,0x0f,0x0b,0x0c,0x01,0x03,0x09,0x07,0x0c,0x03, 0x07,0x0a,0x04,0x0f,0x06,0x0f,0x0e,0x09,0x05,0x01,0x0a,0x0a,0x01,0x09, 0x06,0x07,0x09,0x0d}; //byte转换为NSData类型,以便下边加密方法的调用 NSData *keyData = [[NSData alloc] initWithBytes:keyByte length:32]; // NSData *cipherTextData = [plainTextData AES256EncryptWithKey:keyData]; Byte *plainTextByte = (Byte *)[cipherTextData bytes]; for(int i=0;i<[cipherTextData length];i++){ printf("%x",plainTextByte[i]); } } @end
本文原文转至:http://my.oschina.net/nicsun/blog/95632?p=2#comments
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。