单向加密就是用同一个密钥去加密和解密。
一.AES
支持密钥128位,192位,256位(常用的是128位 md5, 256位 sha256)
算法/工作模式/填充方式的概念:
算法是:AES
工作模式:ECB/CBC 默认情况下iOS是CBC的,我提供的例子是ECB的的工作模式,所以iOS在设置加密参数的时候要添加参数 kCCOptionECBMode
填充方式:kCCOptionPKCS7Padding iOS似乎只支持这样的填充方式,java有很多填充方式,但是就不支持这个,所以要引用第三方包bouncycastle
java代码
public static void main(String[] args) throws Exception { String str = "欢迎光临JerryVon的博客"; System.out.println("原文:" + str); //初始化密钥 // byte[] key = AES256Encryption.initkey(); byte[] key = sha256eccrypt("pwd123"); System.out.print("密钥:"); System.out.print(MD5Utils.hexString(key)); //加密数据 byte[] data = AES256Encryption.encrypt(str.getBytes(), key); System.out.print("加密后:"); System.out.println("加密后的:" + (new sun.misc.BASE64Encoder()).encode(data)); //解密数据 data = AES256Encryption.decrypt(data, key); System.out.println("解密后:" + new String(data)); } 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); } public static byte[] decrypt(byte[] data, byte[] key) throws Exception { //欢迎密钥 Key k = toKey(key); /** * 实例化 * 使用 PKCS7PADDING 填充方式,按如下方式实现,就是调用bouncycastle组件实现 * Cipher.getInstance(CIPHER_ALGORITHM,"BC") */ Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); //初始化,设置为解密模式 cipher.init(Cipher.DECRYPT_MODE, k); //执行操作 return cipher.doFinal(data); }
Objective-C调用代码
NSString* message = @"欢迎光临JerryVon的博客"; NSString* password @"pwd123"; //pwd sha256作为密钥 NSData* pwdData = [[password dataUsingEncoding:NSUTF8StringEncoding] SHA256Hash] ; //pwd md5 128作为密钥 //NSData* pwdData = [[password dataUsingEncoding:NSUTF8StringEncoding] MD5Sum] ; //16进制String 密钥 NSString* hexPwdString=[pwdData hexString]; NSLog(@"%@",hexPwdString); //加密字符串并转BASE64 NSData *encryptedData = [[message dataUsingEncoding:NSUTF8StringEncoding] AES256EncryptedDataUsingKey:pwdData error:nil]; NSString* encrypted64EncodeString = [GTMBase64 stringByEncodingData:encryptedData]; NSLog(@"%@",encrypted64EncodeString); //解密 NSData* decryptedData =[[GTMBase64 decodeString:encrypted64EncodeString] decryptedAES256DataUsingKey:pwdData error:nil]; NSString* srcString = [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding];
调用的代码如下:(没有iv的情况,注意option送的值,默认的CBC模式我没有深入研究过)
- (NSData *) AES256EncryptedDataUsingKey: (id) key error: (NSError **) error { CCCryptorStatus status = kCCSuccess; NSData * result = [self dataEncryptedUsingAlgorithm: kCCAlgorithmAES128 key: key options: kCCOptionPKCS7Padding| kCCOptionECBMode error: &status]; if ( result != nil ) return ( result ); if ( error != NULL ) *error = [NSError errorWithCCCryptorStatus: status]; return ( nil ); }
具体调用的底层方法如下:
- (NSData *) dataEncryptedUsingAlgorithm: (CCAlgorithm) algorithm key: (id) key initializationVector: (id) iv options: (CCOptions) options error: (CCCryptorStatus *) error { CCCryptorRef cryptor = NULL; CCCryptorStatus status = kCCSuccess; // NSParameterAssert([key isKindOfClass: [NSData class]] || [key isKindOfClass: [NSString class]]); // NSParameterAssert(iv == nil || [iv isKindOfClass: [NSData class]] || [iv isKindOfClass: [NSString class]]); NSMutableData * keyData, * ivData; if ( [key isKindOfClass: [NSData class]] ) keyData = (NSMutableData *) [key mutableCopy]; else keyData = [[key dataUsingEncoding: NSUTF8StringEncoding] mutableCopy]; if ( [iv isKindOfClass: [NSString class]] ) ivData = [[iv dataUsingEncoding: NSUTF8StringEncoding] mutableCopy]; else ivData = (NSMutableData *) [iv mutableCopy]; // data or nil [keyData autorelease]; [ivData autorelease]; // ensure correct lengths for key and iv data, based on algorithms FixKeyLengths( algorithm, keyData, ivData ); status = CCCryptorCreate( kCCEncrypt, algorithm, options, [keyData bytes], [keyData length], [ivData bytes], &cryptor ); if ( status != kCCSuccess ) { if ( error != NULL ) *error = status; return ( nil ); } NSData * result = [self _runCryptor: cryptor result: &status]; if ( (result == nil) && (error != NULL) ) *error = status; CCCryptorRelease( cryptor ); return ( result ); }
以上是加密过程,解密过程类似的逆操作
密码原文:pwd123
密码HEX_String:3838BD5806D32CD91144865AA822B9551417DD2796C163D390BAA7074D3067A7
加密内容原文:欢迎光临JerryVon的博客
AES加密BASE64:amgtoKdeIi+q+RbbUFE7o5xVn4pUsRy0SdTuGpByk7E=
二.DES/3DES
DES、3DES的加密解密代码基本和AES相同,只是在加密代码处设置下相应参数就可以了,具体大家可以查看文档。
DES密钥长度64位、3DES密钥长度192位
参考资料: