现在的位置: 首页 > 综合 > 正文

ios&java 常用加密(二)单向加密

2017年08月13日 ⁄ 综合 ⁄ 共 4367字 ⁄ 字号 评论关闭

单向加密就是用同一个密钥去加密和解密。

一.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


转载自:http://blog.csdn.net/jerryvon/article/details/22691327

抱歉!评论已关闭.