(iOS)Base64加密和DES加密、以及JAVA和iOS中DES加密統一性問題


我們在項目中為了安全方面的考慮,通常情況下會選擇一種加密方式對需要安全性的文本進行加密,而Base64加密和DES64加密是常用的加密算法。我記得我在前一個項目中使用的就是這兩種加密算法的結合:Base64 + DES加密。當然這需要移動端和后台服務器做一個統一。

1、Base64加解密

值得一提的是:apple提供了基礎的Base64加解密算法。這樣我們就可以直接使用方法去實現Base64加解密。先看一下apple都提供了哪些方法:

@interface NSData (NSDataBase64Encoding) /* Create an NSData from a Base-64 encoded NSString using the given options. By default, returns nil when the input is not recognized as valid Base-64. */
- (nullable instancetype)initWithBase64EncodedString:(NSString *)base64String options:(NSDataBase64DecodingOptions)options NS_AVAILABLE(10_9, 7_0); /* Create a Base-64 encoded NSString from the receiver's contents using the given options. */
- (NSString *)base64EncodedStringWithOptions:(NSDataBase64EncodingOptions)options NS_AVAILABLE(10_9, 7_0); /* Create an NSData from a Base-64, UTF-8 encoded NSData. By default, returns nil when the input is not recognized as valid Base-64. */
- (nullable instancetype)initWithBase64EncodedData:(NSData *)base64Data options:(NSDataBase64DecodingOptions)options NS_AVAILABLE(10_9, 7_0); /* Create a Base-64, UTF-8 encoded NSData from the receiver's contents using the given options. */
- (NSData *)base64EncodedDataWithOptions:(NSDataBase64EncodingOptions)options NS_AVAILABLE(10_9, 7_0); @end

 

 

@interface NSData (NSDeprecated) /* These methods first appeared in NSData.h on OS X 10.9 and iOS 7.0. 
They are deprecated in the same releases in favor of the methods in the NSDataBase64Encoding category.
However, these methods have existed for several releases, so they may be used for applications targeting releases prior to OS X 10.9 and iOS 7.0.
*/ - (nullable id)initWithBase64Encoding:(NSString *)base64String NS_DEPRECATED(10_6, 10_9, 4_0, 7_0); - (NSString *)base64Encoding NS_DEPRECATED(10_6, 10_9, 4_0, 7_0); @end

 

 

我們先創建一個NSData,再去一條一條的分析以上的方法

NSData *data = [@"Base64 encoding string" dataUsingEncoding:NSUTF8StringEncoding];

 

(1)創建一個Data(從一個Base64編碼字符串使用給出的設置創建一個Data)

NSData *dataFromBase64String = [[NSData alloc]initWithBase64EncodedString:base64String options:0];

 

(2)創建一個Base64編碼字符串(從接受者內容創建)

NSString *base64String = [data base64EncodedStringWithOptions:0];

 

(3)創建一個Data(從一個Base64、UTF-8編碼的Data創建)

NSData *base64AndUTFData = [base64Data initWithBase64EncodedData:base64Data options:0];

 

(4)創建一個Base64、UTF-8編碼的Data(從接受者內容創建)

NSData *base64Data = [data base64EncodedDataWithOptions:0];

 

當然,我們最后也可以將Data轉化成String類型。

 NSString *base64Decoded = [[NSString alloc]initWithData:dataFromBase64String encoding:NSUTF8StringEncoding];

 

 

以上是Base64加解密方法。下面我們看看DES的加解密。

 

 

 

 2、DES加解密

我們都知道安卓和后台可以使用統一的代碼去解決這個問題,這也是java的優勢之一吧。這里我會附一段java的代碼。主要是為了下面說明java和iOS端實現中需要注意的地方(也是不同點)。

為了使說明更方便一些,我們先看一下java的DES加密方法:

/** * EDS加密 * @param originalStr * @return */
    public static String Encrypt(String originalStr) { String result = null; byte[] tmpOriginalStr = null; try { if (!Tools.isEmpty(originalStr)) { tmpOriginalStr = originalStr.getBytes("utf-8"); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); DESKeySpec dks = new DESKeySpec(KEY); SecretKey secretKey = keyFactory.generateSecret(dks); IvParameterSpec param = new IvParameterSpec(IV); Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, secretKey,param); byte[] tmpEncypt = cipher.doFinal(tmpOriginalStr); if (tmpEncypt != null) { result = Base64.encodeToString(tmpEncypt,Base64.NO_WRAP); } } } catch (Exception e) { Log.e("Erro",e.getMessage()); } return result; }

我們可以看出Java針對DES加密算法默認使用的是CBC模式,對齊方式采用的是PKCS5Padding。


 

而OC中的加密並不是java中的形式實現加密的,接下來我們看一看OC中實現DES加密的代碼:

#pragma mark- 加密算法
+(NSString *) encryptUseDES:(NSString *)plainText //key:(NSString *)key
{ NSString *ciphertext = nil; NSData *textData = [plainText dataUsingEncoding:NSUTF8StringEncoding]; NSUInteger dataLength = [textData length]; unsigned char buffer[1024 * 5]; memset(buffer, 0, sizeof(char)); size_t numBytesEncrypted = 0; CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmDES, kCCOptionPKCS7Padding, [key UTF8String], kCCKeySizeDES, [iv UTF8String], [textData bytes], dataLength, buffer, 1024, &numBytesEncrypted); if (cryptStatus == kCCSuccess) { NSData *data = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesEncrypted]; ciphertext = [data base64EncodedStringWithOptions:0]; } return ciphertext; }

 先說一下代碼中紅色里面的綠色部分:key和iv 。key:是DES加密的公鑰。而iv:是初始化的矢量。兩者都是DES加密的關鍵參數。這個是必須要和Android、后台有個統一的。

 我們可以看出OC使用的是kCCOptionPKCS7Padding對齊方式。而java中很明確的指出使用的是PKCS5Padding。接下來我們點進去看看OC中給出的對齊選擇有哪些,我直接以代碼的形式展示出來:

enum { /* options for block ciphers */ kCCOptionPKCS7Padding = 0x0001, kCCOptionECBMode = 0x0002
    /* stream ciphers currently have no options */ };

 OC中給出的是 kCCOptionECBMode 和 kCCOptionPKCS7Padding 這兩種選擇。那么,問題現在出現了。java中的DES加密算法有很多種,例如:ECB,CBC,OFB,CFB等。

java 和 OC的DES加密怎樣才能實現一致性呢?(這也是我在項目中遇到的問題)。


 

查閱很多資料,再加上自己的很多次測試,得出的結果如下:

在JAVA中使用這種方式加密:"DES/CBC/PKCS5Padding"  對應的Object-C的是 kCCOptionPKCS7Padding

而使用 "DES/ECB/PKCS5Padding" 對應的Object-C的是   kCCOptionPKCS7Padding | kCCOptionECBMod 

覺得似乎OC目前只支持這兩種方式的加密。當然結果是已經得到驗證的。

 

注意:md5加密(iOS SDK中自帶了CommonCrypto)出現警告⚠️ 。

解決方法添加:引入函數定義的頭文件

#import <CommonCrypto/CommonDigest.h>

 

 

 

其他鏈接:

Objective C與Java之間的DES加解密實現

iOS 7: Base64 Encode and Decode NSData and NSString Objects

 

 這里附上demo:https://github.com/Wheat-Qin/Base64-DES

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM