首页 > 代码库 > [掌眼]iOS / Android / java / node.js 通用的 AES256 加解密算法

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

example.m

NSString *text = @"text";NSString *key32 = @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";    NSData *data =http://www.mamicode.com/ [text dataUsingEncoding:NSUTF8StringEncoding];NSString *encryptedData = http://www.mamicode.com/[[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==