码迷,mamicode.com
首页 > 移动开发 > 详细

[掌眼]iOS / Android / java / node.js 通用的 AES256 加解密算法

时间:2014-08-12 21:46:24      阅读:1144      评论:0      收藏:0      [点我收藏+]

标签:des   android   style   blog   color   java   os   io   

example.m

NSString *text = @"text";
NSString *key32 = @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
    
NSData *data = [text dataUsingEncoding:NSUTF8StringEncoding];
NSString *encryptedData = [[data AES256EncryptWithKey:key32] base64EncodedStringWithOptions:0];
 
NSLog(@"%@",encryptedData); # => QfpLKBn20BZI1NIhigOo6g==

NSData+AES256.m

- (NSData *)AES256EncryptWithKey:(NSString *)key {
    // ‘key‘ should be 32 bytes for AES256, will be null-padded otherwise
    char keyPtr[kCCKeySizeAES256+1]; // room for terminator (unused)
    bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)
    
    // fetch key data
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    
    NSUInteger dataLength = [self length];
    
    //See the doc: For block ciphers, the output size will always be less than or
    //equal to the input size plus the size of one block.
    //That‘s why we need to add the size of one block here
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    
    size_t numBytesEncrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
                                          keyPtr, kCCKeySizeAES256,
                                          NULL /* initialization vector (optional) */,
                                          [self bytes], dataLength, /* input */
                                          buffer, bufferSize, /* output */
                                          &numBytesEncrypted);
    if (cryptStatus == kCCSuccess) {
        //the returned NSData takes ownership of the buffer and will free it on deallocation
        return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
    }
    
    free(buffer); //free the buffer;
    return nil;
}
 
- (NSData *)AES256DecryptWithKey:(NSString *)key {
    // ‘key‘ should be 32 bytes for AES256, will be null-padded otherwise
    char keyPtr[kCCKeySizeAES256+1]; // room for terminator (unused)
    bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)
    
    // fetch key data
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    
    NSUInteger dataLength = [self length];
    
    //See the doc: For block ciphers, the output size will always be less than or
    //equal to the input size plus the size of one block.
    //That‘s why we need to add the size of one block here
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    
    size_t numBytesDecrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
                                          keyPtr, kCCKeySizeAES256,
                                          NULL /* initialization vector (optional) */,
                                          [self bytes], dataLength, /* input */
                                          buffer, bufferSize, /* output */
                                          &numBytesDecrypted);
    
    if (cryptStatus == kCCSuccess) {
        //the returned NSData takes ownership of the buffer and will free it on deallocation
        return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
    }
    
    free(buffer); //free the buffer;
    return nil;
}

AES256.java

/**
 * Encodes a String in AES-256 with a given key
 *
 * @param context
 * @param password
 * @param text
 * @return String Base64 and AES encoded String
 */
public static String encode(String keyString, String stringToEncode) throws NullPointerException {
    if (keyString.length() == 0 || keyString == null) {
        throw new NullPointerException("Please give Password");
    }
    
    if (stringToEncode.length() == 0 || stringToEncode == null) {
        throw new NullPointerException("Please give text");
    }
    
    try {
        SecretKeySpec skeySpec = getKey(keyString);
        byte[] clearText = stringToEncode.getBytes("UTF8");
        
        // IMPORTANT TO GET SAME RESULTS ON iOS and ANDROID
        final byte[] iv = new byte[16];
        Arrays.fill(iv, (byte) 0x00);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
        
        // Cipher is not thread safe
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivParameterSpec);
        
        String encrypedValue = Base64.encodeToString(cipher.doFinal(clearText), Base64.DEFAULT);
        Log.d("jacek", "Encrypted: " + stringToEncode + " -> " + encrypedValue);
        return encrypedValue;
        
    } catch (InvalidKeyException e) {
        e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (BadPaddingException e) {
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
        e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
        e.printStackTrace();
    } catch (InvalidAlgorithmParameterException e) {
        e.printStackTrace();
    }
    return "";
}
 
/**
 * Decodes a String using AES-256 and Base64
 *
 * @param context
 * @param password
 * @param text
 * @return desoded String
 */
public String decode(String password, String text) throws NullPointerException {
    
    if (password.length() == 0 || password == null) {
        throw new NullPointerException("Please give Password");
    }
    
    if (text.length() == 0 || text == null) {
        throw new NullPointerException("Please give text");
    }
    
    try {
        SecretKey key = getKey(password);
        
        // IMPORTANT TO GET SAME RESULTS ON iOS and ANDROID
        final byte[] iv = new byte[16];
        Arrays.fill(iv, (byte) 0x00);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
        
        byte[] encrypedPwdBytes = Base64.decode(text, Base64.DEFAULT);
        // cipher is not thread safe
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
        cipher.init(Cipher.DECRYPT_MODE, key, ivParameterSpec);
        byte[] decrypedValueBytes = (cipher.doFinal(encrypedPwdBytes));
        
        String decrypedValue = new String(decrypedValueBytes);
        Log.d(LOG_TAG, "Decrypted: " + text + " -> " + decrypedValue);
        return decrypedValue;
        
    } catch (InvalidKeyException e) {
        e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (BadPaddingException e) {
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
        e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
        e.printStackTrace();
    } catch (InvalidAlgorithmParameterException e) {
        e.printStackTrace();
    }
    return "";
}
 
/**
 * Generates a SecretKeySpec for given password
 *
 * @param password
 * @return SecretKeySpec
 * @throws UnsupportedEncodingException
 */
private static SecretKeySpec getKey(String password) throws UnsupportedEncodingException {
    
    // You can change it to 128 if you wish
    int keyLength = 256;
    byte[] keyBytes = new byte[keyLength / 8];
    // explicitly fill with zeros
    Arrays.fill(keyBytes, (byte) 0x0);
    
    // if password is shorter then key length, it will be zero-padded
    // to key length
    byte[] passwordBytes = password.getBytes("UTF-8");
    int length = passwordBytes.length < keyBytes.length ? passwordBytes.length : keyBytes.length;
    System.arraycopy(passwordBytes, 0, keyBytes, 0, length);
    SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
    return key;
}

node.js

crypto = require(‘crypto‘)
key = ‘xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx‘
iv = new Buffer(16)
iv.fill(0)
 
text = ‘text‘
 
cipher = crypto.createCipheriv(‘aes-256-cbc‘, key, iv)
output = cipher.update(‘text‘, ‘utf8‘, ‘base64‘)
output += cipher.final(‘base64‘)
 
console.log output # => QfpLKBn20BZI1NIhigOo6g==

 

[掌眼]iOS / Android / java / node.js 通用的 AES256 加解密算法,布布扣,bubuko.com

[掌眼]iOS / Android / java / node.js 通用的 AES256 加解密算法

标签:des   android   style   blog   color   java   os   io   

原文地址:http://www.cnblogs.com/yipu/p/3908458.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!