IOS 与 PHP 通信加密,使用AES 128 CBC no padding

这个网上的资料真实浩如烟海,但是真正有价值的屈指可数

自己尝试了一天多,终于还是搞定了。

再次要感谢网上的前辈么。

比如下面这个关于php和java端的实现:

http://my.oschina.net/Jacker/blog/86383

关于php和java端的实现。

再比如下面这个关于ios端的实现:

http://www.cnblogs.com/wanyakun/p/3403352.html

为何要采用 no padding 这种形式:

AES加密如果原输入数据不够16字节的整数位,就要补齐,如果采用

pkcs7或者pkcs5这种加密方式,末端添加的数据可能是0x1,0x2,0x3,不固定,

在解码后需要把末端多余的字符去掉,就显得比较棘手。

如果不管补齐多少位,末端都是‘\0‘,去掉的话比较容易操作。

好了,再次确认一下,这里使用的是  AES128 CBC no padding加密解密方式。

先上ios端的代码:

 <pre class="objc" name="code">//
//  AES128.m
//  login
//
//  Created by wangdan on 15-3-3.
//  Copyright (c) 2015年 wangdan. All rights reserved.
//

#import "AES128.h"

#import <CommonCrypto/CommonCryptor.h>
#import "GTMBase64.h"

@implementation AES128

+(NSString *)AES128Encrypt:(NSString *)plainText withKey:(NSString *)key
{

    if( ![self validKey:key] ){
        return nil;
    }

    char keyPtr[kCCKeySizeAES128+1];
    memset(keyPtr, 0, sizeof(keyPtr));
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

    char ivPtr[kCCBlockSizeAES128+1];
    memset(ivPtr, 0, sizeof(ivPtr));
    [key getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];

    NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding];
    NSUInteger dataLength = [data length];

    int diff = kCCKeySizeAES128 - (dataLength % kCCKeySizeAES128);
    unsigned long newSize = 0;

    if(diff > 0)
    {
        newSize = dataLength + diff;
        NSLog(@"diff is %d",diff);
    }

    char dataPtr[newSize];
    memcpy(dataPtr, [data bytes], [data length]);
    for(int i = 0; i < diff; i++)
    {
        dataPtr[i + dataLength] =0x0000;
    }

    size_t bufferSize = newSize + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    memset(buffer, 0, bufferSize);

    size_t numBytesCrypted = 0;

    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
                                          kCCAlgorithmAES128,
                                          0x0000,
                                          [key UTF8String],
                                          kCCKeySizeAES128,
                                          [key UTF8String],
                                          dataPtr,
                                          sizeof(dataPtr),
                                          buffer,
                                          bufferSize,
                                          &numBytesCrypted);

    if (cryptStatus == kCCSuccess) {
        NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesCrypted];
        return [GTMBase64 stringByEncodingData:resultData];
    }
    free(buffer);
    return nil;
}

+(NSString *)processDecodedString:(NSString *)decoded
{
    if( decoded==nil || decoded.length==0 ){
        return nil;
    }
    const char *tmpStr=[decoded UTF8String];
    int i=0;

    while( tmpStr[i]!='\0' )
    {
        i++;
    }
    NSString *final=[[NSString alloc]initWithBytes:tmpStr length:i encoding:NSUTF8StringEncoding];
    return final;

}

+(NSString *)AES128Decrypt:(NSString *)encryptText withKey:(NSString *)key
{

    if( ![self validKey:key] ){
        return nil;
    }

    char keyPtr[kCCKeySizeAES128 + 1];
    memset(keyPtr, 0, sizeof(keyPtr));
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

    char ivPtr[kCCBlockSizeAES128 + 1];
    memset(ivPtr, 0, sizeof(ivPtr));
    [key getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];

    NSData *data = [GTMBase64 decodeData:[encryptText dataUsingEncoding:NSUTF8StringEncoding]];
    NSUInteger dataLength = [data length];
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);

    size_t numBytesCrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
                                          kCCAlgorithmAES128,
                                          0x0000,
                                          [key UTF8String],
                                          kCCBlockSizeAES128,
                                          [key UTF8String],
                                          [data bytes],
                                          dataLength,
                                          buffer,
                                          bufferSize,
                                          &numBytesCrypted);
    if (cryptStatus == kCCSuccess) {
        NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesCrypted];

        NSString *decoded=[[NSString alloc] initWithData:resultData encoding:NSUTF8StringEncoding];
        return [self processDecodedString:decoded];
    }

    free(buffer);
    return nil;

}

+(BOOL)validKey:(NSString*)key
{
    if( key==nil || key.length !=16 ){
        return NO;
    }
    return YES;
}

-(NSString *)processDecodedString:(NSString *)decoded
{
    if( decoded==nil || decoded.length==0 ){
        return nil;
    }
    const char *tmpStr=[decoded UTF8String];
    int i=0;

    while( tmpStr[i]!='\0' )
    {
        i++;
    }
    NSString *final=[[NSString alloc]initWithBytes:tmpStr length:i encoding:NSUTF8StringEncoding];
    return final;

}

@end

上述代码需要说明的是,进行AES编码时,输入编码必须是16字节的整数倍,不然调用ios 的系统api会报错 -4003

补齐的字节数全部填充为0

另外  processDecodedString这个函数为了把解码后的字符串,末尾去掉‘\0‘

下面是PHP端的代码,这个代码是大神些写的啊,经过实际实验是能使用的:

<?php
$privateKey = "1234567812345678";
$iv     = "1234567812345678";
$data   = "Test String";

//加密
$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $privateKey, $data, MCRYPT_MODE_CBC, $iv);
echo(base64_encode($encrypted));
echo '<br/>';

//解密
$encryptedData = base64_decode("2fbwW9+8vPId2/foafZq6Q==");
$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $privateKey, $encryptedData, MCRYPT_MODE_CBC, $iv);
echo($decrypted);
?>
时间: 2024-11-09 01:09:06

IOS 与 PHP 通信加密,使用AES 128 CBC no padding的相关文章

[加密]在AES的CBC模式下 pydes vs crypto

因为项目中有个非常重要的功能,并发量和访问量都很大,里面使用了pydes,总感觉它的性能不太好,从别人的对比来看,性能差距应该挺大,但还是自己测试下吧. 自己测试,心里更有数. 环境 macos 10.10.5 python2.7 pyDes (2.0.1) 纯python pycrypto (2.6.1) 底层依赖C 测试 由于加密,解密方式很多,这里只测试一种,大概看下在完成相似功能性能差别就好(对于加密算法的基本原理还要学习) pydes代码 #coding:utf-8 #file:pyd

iOS开发——AES加密(128 CBC/ECB NoPadding/PKCS7Padding)

项目开发过程中,经常会使用各种加密手段来保证数据的安全性,常见的有MD5,DES,AES等等.摘取百度百科AES词条的简介:AES即高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准.这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用.经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在20

C# AES 128加密,解密示例

/// <summary> /// AES加密 /// </summary> /// <param name="clearTxt"></param> /// <returns></returns> public static string AesEncrypt(string clearTxt) { string secretKey = "I15TMSLO0KXUWTHO"; byte[] key

C#实现DES加密解密,AES加密解密

DES算法描述简介: DES是Data Encryption Standard(数据加密标准)的缩写.它是由IBM公司研制的一种加密算法,美国国家标准局于1977年公布把它作为非机要部门使用的数据加密标准:它是一个分组加密算法,他以64位为分组对数据加密.同时DES也是一个对称算法:加密和解密用的是同一个算法.它的密匙长度是56位(因为每个第8 位都用作奇偶校验),密匙可以是任意的56位的数,而且可以任意时候改变. /// <summary>   /// DES加密   /// </su

iOS,Android,.NET通用AES加密算法

原文:iOS,Android,.NET通用AES加密算法 这两天为移动App开发API,结果实现加密验证时碰到一大坑.这里不得不吐槽下又臭又硬的iOS,Windows Server无法解密出正确的结果,Android则可以,后来使用了通用的AES256加密算法才最终搞定. 搞服务器端小伙伴没有接触过iOS,所以也没料到过这种情形.他使用了AES128 with IV的加密算法,Android端可以顺利通过加密验证. 但是iOS端使用AES128算法后出现问题,虽然可以在本地加密解密,但是无法被服

【Android工具】DES终结者加密时报——AES加密演算法

转载请注明出处:http://blog.csdn.net/zhaokaiqiang1992 在前面的两篇文章中.我们介绍了DES算法,3DES算法以及他们的Android程序实现,并研究了怎样才干实现不同平台下加密算法的一致性. 只是话说起来,DES算法是在1976年被美国的国家标准局定为联邦资料的加密标准的,到如今已经接近40年了.我们都知道.在计算机的世界里有一个摩尔定律.就是每过18个月.计算机的晶体管的数量就会翻一番,相应的计算速度也会翻倍,尽管如今的发展速度有所放缓,可是每过三年左右,

IOS开发之----常用加密方法

本文转载至 http://blog.csdn.net/wildfireli/article/details/23191983 (AES.MD5.Base64) 分类: iPhone 2014-04-08 16:30 187人阅读 评论(0) 收藏 举报 目录(?)[+] 1.AES加密 NSData+AES.h文件 // // NSData-AES.h // Smile // // Created by Gary on 12-11-24. // Copyright (c) 2012年 BOX.

信息安全-加密:AES 加密

ylbtech-信息安全-加密:AES 加密 高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准.这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用.经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准.2006年,高级加密标准已然成为对称密钥加密中最流行的

【REACT NATIVE 系列教程之十二】REACT NATIVE(JS/ES)与IOS(OBJECT-C)交互通信

一用到跨平台的引擎必然要有引擎与各平台原生进行交互通信的需要.那么Himi先讲解React Native与iOS之间的通信交互. 本篇主要分为两部分讲解:(关于其中讲解的OC语法等不介绍,不懂的请自行学习) 1. React Native 访问iOS 2. iOS访问React Native     一:React Native 访问iOS 1. 我们想要JS调用OC函数,就要实现一个"RCTBridgeModule"协议的Objective-C类 所以首先我们先创建一个oc新类,