单向加密就是用同一个密钥去加密和解密。
一.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] <span style="font-family: Arial, Helvetica, sans-serif;">MD5Sum</span><span style="font-family: Arial, Helvetica, sans-serif;">] ;</span>
//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];
Objective-C核心代码
调用的代码如下:(没有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位
参考资料:
AES加密问题:http://my.oschina.net/nicsun/blog/95632