iOS与PHP/Android AES128 ECB NoPadding加密
来自: http://www.henishuo.com/ios-aes128-ecb-nopadding/
前言
谈谈AES加密,网上有很多的版本,当我没有真正在加密安全问题前,总以为百度出来某个AES加密算法就可以直接使用,实际上当我真正要做加密时,遇到了很多的坑,原来不是拿过来就能用的。写下本篇文章,记录下曾经遇到的坑,严防以后再出现同样的坑。
AES规则
原输入数据不够16字节的整数位时,就要补齐。因此就会有padding,若使用不同的padding,那么加密出来的结果也会不一样。
AES加密算法
苹果提供给我们的API只有这一个函数用来加密或者解密:
CCCryptorStatus CCCrypt( CCOperation op, /* kCCEncrypt, etc. */ CCAlgorithm alg, /* kCCAlgorithmAES128, etc. */ CCOptions options, /* kCCOptionPKCS7Padding, etc. */ const void *key, size_tkeyLength, const void *iv, /* optional initialization vector */ const void *dataIn, /* optional per op and alg */ size_tdataInLength, void *dataOut, /* data RETURNED here */ size_tdataOutAvailable, size_t*dataOutMoved) __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0);
- 其中第一个 CCOperation 只有两个值,要么是 kCCEncrypt 表示加密,要么是 kCCDecrypt 表示解密。
- 第二个参数表示加密的算法,它只有以下向种类型:
enum { kCCAlgorithmAES128 = 0, kCCAlgorithmAES = 0, kCCAlgorithmDES, kCCAlgorithm3DES, kCCAlgorithmCAST, kCCAlgorithmRC4, kCCAlgorithmRC2, kCCAlgorithmBlowfish };typedef uint32_tCCAlgorithm;
我们这里使用的是 kCCAlgorithmAES128 表示使用AES128位加密。
- 第三个参数表示选项,这里使用的是 kCCOptionECBMode ,表示ECB:
enum { /* options for block ciphers */ kCCOptionPKCS7Padding = 0x0001, kCCOptionECBMode = 0x0002 /* stream ciphers currently have no options */};typedef uint32_tCCOptions;
- 第四个参数表示加密/解密的密钥。
- 第五个参数keyLength表示密钥的长度。
- 第六个参数iv是个固定值,通过直接使用密钥即可。大家一定要注视这个参数,如果安卓、服务端和iOS端不统一,那么加密结果就会不一样,解密可能能解出来,但是解密后在末尾会出现一些\0、\t之类的。
- 第七个参数dataIn表示要加密/解密的数据。
- 第八个参数dataInLength表示要加密/解密的数据的长度。
- 第九个参数dataOut用于接收加密后/解密后的结果。
- 第十个参数dataOutAvailable表示加密后/解密后的数据的长度。
- 第十一个参数dataOutMoved表示实际加密/解密的数据的长度。(因为有补齐)
加密算法
依赖于第三方库: GTMBase64 ,这个库已经几年没有维护了,现在还是MRC版本,要使用请到GITHUB查看使用教程,那里有ARC接入说明:
+ (NSString *)hyb_AESEncrypt:(NSString *)plainTextpassword:(NSString *)key { if (key == nil || (key.length != 16 && key.length != 32)) { return nil; } char keyPtr[kCCKeySizeAES128+1]; memset(keyPtr, 0, sizeof(keyPtr)); [keygetCString:keyPtrmaxLength:sizeof(keyPtr)encoding:NSUTF8StringEncoding]; char ivPtr[kCCBlockSizeAES128+1]; memset(ivPtr, 0, sizeof(ivPtr)); [keygetCString:ivPtrmaxLength:sizeof(ivPtr)encoding:NSUTF8StringEncoding]; NSData* data = [plainTextdataUsingEncoding:NSUTF8StringEncoding]; NSUInteger dataLength = [datalength]; int diff = kCCKeySizeAES128 - (dataLength % kCCKeySizeAES128); unsigned long newSize = 0; if(diff > 0) { newSize = dataLength + diff; } char dataPtr[newSize]; memcpy(dataPtr, [databytes], [datalength]); for(int i = 0; i < diff; i++) { // 这里是关键,这里是使用NoPadding的 dataPtr[i + dataLength] = 0x0000; } size_tbufferSize = newSize + kCCBlockSizeAES128; void *buffer = malloc(bufferSize); memset(buffer, 0, bufferSize); size_tnumBytesCrypted = 0; CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionECBMode, [keyUTF8String], kCCKeySizeAES128, ivPtr, dataPtr, sizeof(dataPtr), buffer, bufferSize, &numBytesCrypted); if (cryptStatus == kCCSuccess) { NSData *resultData = [NSDatadataWithBytesNoCopy:bufferlength:numBytesCrypted]; return [GTMBase64stringByEncodingData:resultData]; } free(buffer); return nil;}
对于加密算法,大家一定要注意,保证iOS、安卓、服务端的加密规则是一定的,建议统一使用No Padding的,这里使用No Padding是这样的:
for(int i = 0; i < diff; i++) { // 这里是关键,这里是使用NoPadding的 dataPtr[i + dataLength] = 0x0000;}
其实所谓Padding就是指在位数不够需要补齐时,使用什么来填充,而No Padding就是使用16个0,对应0x0000.如果三端不统一,加密出来就算能解密,也会出现一些奇怪的字符,甚至会有部分乱码。
另外,这里使用的是 kCCOptionECBMode ,也就是ECB。在安卓端和PHP端,也得使用ECB。在调试过程中,发现PHP使用CBC解密不了IOS端的。于是改成了使用ECB。
解密算法
依赖于第三方库: GTMBase64 ,这个库已经几年没有维护了,现在还是MRC版本,要使用请到GITHUB查看使用教程,那里有ARC接入说明:
+ (NSString *)hyb_AESDecrypt:(NSString *)encryptTextpassword:(NSString *)key { if (key == nil || (key.length != 16 && key.length != 32)) { return nil; } char keyPtr[kCCKeySizeAES128 + 1]; memset(keyPtr, 0, sizeof(keyPtr)); [keygetCString:keyPtrmaxLength:sizeof(keyPtr)encoding:NSUTF8StringEncoding]; char ivPtr[kCCBlockSizeAES128 + 1]; memset(ivPtr, 0, sizeof(ivPtr)); [keygetCString:ivPtrmaxLength:sizeof(ivPtr)encoding:NSUTF8StringEncoding]; NSData *data = [GTMBase64decodeData:[encryptTextdataUsingEncoding:NSUTF8StringEncoding]]; NSUInteger dataLength = [datalength]; size_tbufferSize = dataLength + kCCBlockSizeAES128; void *buffer = malloc(bufferSize); size_tnumBytesCrypted = 0; CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionECBMode, [keyUTF8String], kCCBlockSizeAES128, ivPtr, [databytes], dataLength, buffer, bufferSize, &numBytesCrypted); if (cryptStatus == kCCSuccess) { NSData *resultData = [NSDatadataWithBytesNoCopy:bufferlength:numBytesCrypted]; NSString *decoded=[[NSString alloc]initWithData:resultDataencoding:NSUTF8StringEncoding]; return decoded; } free(buffer); return nil;}
解密时也得跟加密一样指定为ECB,否则解出来会出现乱码,或者末尾会出现\0、\t之类的符号。
写在最后
开发中总会遇到各种坑,网上查了很多的资料,但是终究没有说明解决的办法,而是只将自己的代码放出来。对于刚接触这方面知识的开发人员来说,是很懵懂的。甚至很多新手会觉得系统就是这样的,我也没办法。其实总会有解决办法的,关键在于与其他各端统一连调。
关注我
Swift/ObjC技术群一:324400294(已满)
Swift/ObjC技术群二:494669518
ObjC/Swift高级群:461252383(注明年限,新手勿扰)
关注微信公众号: iOSDevShares
关注新浪微博账号:标哥Jacky
标哥的GITHUB地址: CoderJackyHuang
支持并捐助
如果您觉得文章对您很有帮忙,希望得到您的支持。您的捐肋将会给予我最大的鼓励,感谢您的支持!
支付宝捐助 | 微信捐助 |
---|---|

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



Laravel vereinfacht die Behandlung von temporären Sitzungsdaten mithilfe seiner intuitiven Flash -Methoden. Dies ist perfekt zum Anzeigen von kurzen Nachrichten, Warnungen oder Benachrichtigungen in Ihrer Anwendung. Die Daten bestehen nur für die nachfolgende Anfrage standardmäßig: $ Anfrage-

Die PHP -Protokollierung ist für die Überwachung und Debugie von Webanwendungen von wesentlicher Bedeutung sowie für das Erfassen kritischer Ereignisse, Fehler und Laufzeitverhalten. Es bietet wertvolle Einblicke in die Systemleistung, hilft bei der Identifizierung von Problemen und unterstützt eine schnellere Fehlerbehebung

Die PHP Client -URL -Erweiterung (CURL) ist ein leistungsstarkes Tool für Entwickler, das eine nahtlose Interaktion mit Remote -Servern und REST -APIs ermöglicht. Durch die Nutzung von Libcurl, einer angesehenen Bibliothek mit Multi-Protokoll-Dateien, erleichtert PHP Curl effiziente Execu

Laravel bietet eine kurze HTTP -Antwortsimulationssyntax und vereinfache HTTP -Interaktionstests. Dieser Ansatz reduziert die Code -Redundanz erheblich, während Ihre Testsimulation intuitiver wird. Die grundlegende Implementierung bietet eine Vielzahl von Verknüpfungen zum Antworttyp: Verwenden Sie Illuminate \ Support \ facades \ http; Http :: fake ([ 'Google.com' => 'Hallo Welt',, 'github.com' => ['foo' => 'bar'], 'Forge.laravel.com' =>

Möchten Sie den dringlichsten Problemen Ihrer Kunden in Echtzeit und Sofortlösungen anbieten? Mit Live-Chat können Sie Echtzeitgespräche mit Kunden führen und ihre Probleme sofort lösen. Sie ermöglichen es Ihnen, Ihrem Brauch einen schnelleren Service zu bieten

In Artikel wird die in PHP 5.3 eingeführte LSB -Bindung (LSB) erörtert, die die Laufzeitauflösung der statischen Methode ermöglicht, um eine flexiblere Vererbung zu erfordern. Die praktischen Anwendungen und potenziellen Perfo von LSB

Alipay PHP ...

In dem Artikel werden Frameworks hinzugefügt, das sich auf das Verständnis der Architektur, das Identifizieren von Erweiterungspunkten und Best Practices für die Integration und Debuggierung hinzufügen.
