博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS,Android,WP, .NET通用AES加密算法
阅读量:5009 次
发布时间:2019-06-12

本文共 8474 字,大约阅读时间需要 28 分钟。

这两天为移动App开发API,结果实现加密验证时碰到一大坑。这里不得不吐槽下又臭又硬的iOS,Windows Server无法解密出正确的结果,Android则可以,后来使用了通用的AES256加密算法才最终搞定。

搞服务器端小伙伴没有接触过iOS,所以也没料到过这种情形。他使用了AES128 with IV的加密算法,Android端可以顺利通过加密验证。

但是iOS端使用AES128算法后出现问题,虽然可以在本地加密解密,但是无法被服务器解密成功。

后来经过多方查找,才了解到一个蛋疼的事实,iOS只支持AES PKCS7Padding算法,在服务器端修改为相应算法后,顺利通过。

这里主要参考,以下给出通用AES算法:

 

Objective-C:

//头文件 #import 
@interface NSData (AES)- (NSData *)AES256EncryptWithKey:(NSString *)key;- (NSData *)AES256DecryptWithKey:(NSString *)key;@end

实现代码:

#import "NSData+AES256.h"#import 
@implementation NSData (AES)-(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;}@end

 

C#:

#region        ///         /// 256位AES加密        ///         ///         /// 
public static string Encrypt(string toEncrypt) { // 256-AES key byte[] keyArray = UTF8Encoding.UTF8.GetBytes(key); byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt); RijndaelManaged rDel = new RijndaelManaged(); rDel.Key = keyArray; rDel.Mode = CipherMode.ECB; rDel.Padding = PaddingMode.PKCS7; ICryptoTransform cTransform = rDel.CreateEncryptor(); byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); return Convert.ToBase64String(resultArray, 0, resultArray.Length); } /// /// 256位AES解密 /// /// ///
public static string Decrypt(string toDecrypt) { // 256-AES key byte[] keyArray = UTF8Encoding.UTF8.GetBytes(key); byte[] toEncryptArray = Convert.FromBase64String(toDecrypt); RijndaelManaged rDel = new RijndaelManaged(); rDel.Key = keyArray; rDel.Mode = CipherMode.ECB; rDel.Padding = PaddingMode.PKCS7; ICryptoTransform cTransform = rDel.CreateDecryptor(); byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); return UTF8Encoding.UTF8.GetString(resultArray); } #endregion

 

Java

import java.io.UnsupportedEncodingException;import java.security.InvalidAlgorithmParameterException;import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import java.util.Arrays;import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.NoSuchPaddingException;import javax.crypto.spec.IvParameterSpec;import javax.crypto.spec.SecretKeySpec;import android.util.Base64;public class AESUtils {    /**      * 加密      * @param content 需要加密的内容      * @param password  加密密码      * @return      */      private static String Key="key";    public static String encode(String stringToEncode) throws NullPointerException {        try {            SecretKeySpec skeySpec = getKey(Key);            byte[] clearText = stringToEncode.getBytes("UTF8");            final byte[] iv = new byte[16];            Arrays.fill(iv, (byte) 0x00);            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivParameterSpec);            String encrypedValue = Base64.encodeToString(cipher.doFinal(clearText), Base64.DEFAULT);            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 "";    }                 private static SecretKeySpec getKey(String password) throws UnsupportedEncodingException {        int keyLength = 256;        byte[] keyBytes = new byte[keyLength / 8];        Arrays.fill(keyBytes, (byte) 0x0);        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;    }        }

 

 Windows Phone&Windows Store:

 

public static string Encrypt(string toEncrypt)        {                        //创建算法提供器            var symmetricAlgorithm = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesEcbPkcs7);            //key处理            IBuffer tempKey = CryptographicBuffer.ConvertStringToBinary(key, BinaryStringEncoding.Utf8);            CryptographicKey cryptKey = symmetricAlgorithm.CreateSymmetricKey(tempKey);            // 将需要加密的数据转换为 IBuffer 类型            var dateBuffer = CryptographicBuffer.ConvertStringToBinary(toEncrypt, BinaryStringEncoding.Utf8);                        try            {                // 加密数据                var encrypted = CryptographicEngine.Encrypt(cryptKey,dateBuffer,null);               // Debug.WriteLine(encrypted);               return CryptographicBuffer.EncodeToBase64String(encrypted);            }            catch (Exception ex)            {                Debug.WriteLine(ex.Message);            }            return null;        }

 

转载于:https://www.cnblogs.com/mantgh/p/4244891.html

你可能感兴趣的文章
Jquery Uploadify3.21.与2.1版本 使用中存在的问题--记录三
查看>>
Linux查看进程的内存占用情况 分类: ubuntu ...
查看>>
[BZOJ 2818]Gcd
查看>>
FORM值传递与地址传递
查看>>
(译)yaml快速教程
查看>>
C:大数相加
查看>>
160. Intersection of Two Linked Lists
查看>>
人生苦短,我用python-- Day11
查看>>
JAVA Bean
查看>>
ehcache memcache redis 三大缓存男高音_转
查看>>
curd_3
查看>>
百度地图API示例之设置地图显示范围
查看>>
Java构造方法、重载及垃圾回收
查看>>
.Net Core AES加密解密
查看>>
Spring Quartz实现任务调度
查看>>
python | 桶排序、冒泡排序、选择排序、去重
查看>>
两个Html页面之间值得传递
查看>>
EasyUI datagrid 的多条件查询
查看>>
Mac升级bash到最新版本
查看>>
利用vagrant打包系统--制作自己的box
查看>>