国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

iOS MT19937隨機數(shù)生成,結合AES-CBC加密算法實現(xiàn)。

這篇具有很好參考價值的文章主要介紹了iOS MT19937隨機數(shù)生成,結合AES-CBC加密算法實現(xiàn)。。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

按處理順序說明:

1. 生成隨機數(shù)序列字符串函數(shù)

生成方法MT19937,初始種子seed,利用C++庫方法,生成:

#include <random> //C++ 庫頭文件引入

NSString * JKJMT19937Seed(uint32_t seed) {
    NSLog(@"MT19937Seed種子:%u",seed);
    NSMutableArray *ranVlues = [NSMutableArray array];
    std::mt19937 rngCPluc2(seed);
    for (int i = 0; i < 64; ++i) {//連續(xù)生產(chǎn)64個隨機數(shù)
        unsigned long ranValue = rngCPluc2();
        NSNumber *rngVal = [NSNumber numberWithUnsignedLong:ranValue];
        [ranVlues addObject:rngVal];
    }
    NSString *ranSeriesStr = [ranVlues componentsJoinedByString:@""];
    NSLog(@"隨機數(shù)值序列拼接字符串key1 = %@",ranSeriesStr);
    return ranSeriesStr;
}

2. 對第一部中的隨機數(shù)序列字符串進行sha256加密,得到64字節(jié)的一個數(shù)據(jù)流函數(shù)。

#import <CommonCrypto/CommonCrypto.h>//加密頭文件

NSString * sha256String(NSString *inputString) {
    const char *str = inputString.UTF8String;
    uint8_t buffer[CC_SHA256_DIGEST_LENGTH];

    CC_SHA256(str, (CC_LONG)strlen(str), buffer);
    NSMutableString *strM = [NSMutableString string];
    for (int i = 0; i < CC_SHA256_DIGEST_LENGTH; i++) {
        [strM appendFormat:@"%02x", buffer[i]];
    }
    return [strM copy];
}

?3. AES-CBC加密解密方法

/*
    CCCrypt方法提供了CBC 和 ECB 兩種AES加密模式,
    如果不傳參數(shù),kCCOptionECBMode,則默認即使CBC模式加密。
    ECB模式不是一種可靠安全的加密模式,推薦使用CBC模式。
    另外也可以通過其他的庫或者方法實現(xiàn)GCM等方式的AES加密。在后面的代碼塊中翻入方法。
*/
NSData *aesCBCEncrypt(NSData *inputData, NSData *keyData, NSData *ivData) {
    NSData *key = keyData;
    // 準備一個初始化向量(IV),IV 的長度需要與 AES 加密模式匹配
    // 在 AES-CBC 模式下,IV 的長度通常為 AES 塊大?。?6 字節(jié))
    NSData *iv = ivData;

    // 創(chuàng)建一個用于存儲加密后數(shù)據(jù)的 NSMutableData 對象
    NSMutableData *encryptedData = [NSMutableData dataWithLength:inputData.length + kCCBlockSizeAES128];
    size_t encryptedDataLength = 0;
    
    // 使用 AES-256 加密(CBC)
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES,
                                          kCCOptionPKCS7Padding,
                                          key.bytes, key.length,
                                          iv.bytes, // 無需傳入 IV
                                          inputData.bytes, inputData.length,
                                          encryptedData.mutableBytes, encryptedData.length,
                                          &encryptedDataLength);
    
    if (cryptStatus == kCCSuccess) {
        encryptedData.length = encryptedDataLength;
        return encryptedData;
    } else {
        NSLog(@"AES-256 加密失敗");
        return nil;
    }
}

NSData *aesCBCDecrypt(NSData *encryptedData, NSData *keyData, NSData *ivData) {
    // 準備一個初始化向量(IV)
    // 在 AES-CBC 模式下,IV 的長度通常為 AES 塊大?。?6 字節(jié))
    NSData *iv = ivData;
    
    // 創(chuàng)建一個用于存儲解密后數(shù)據(jù)的 NSMutableData 對象
    NSMutableData *decryptedData = [NSMutableData dataWithLength:encryptedData.length];
    size_t decryptedDataLength = 0;
    
    // 進行 AES 解密
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES,
                                          kCCOptionPKCS7Padding,
                                          keyData.bytes, keyData.length,
                                          iv.bytes, // 傳入 IV
                                          encryptedData.bytes, encryptedData.length,
                                          decryptedData.mutableBytes, decryptedData.length,
                                          &decryptedDataLength);
    
    if (cryptStatus == kCCSuccess) {
        decryptedData.length = decryptedDataLength;
        return decryptedData;
    } else {
        NSLog(@"AES 解密失敗");
        return nil;
    }
}

/*
? ? CCCrypt方法提供了CBC 和 ECB 兩種AES加密模式,
? ? 如果不傳參數(shù),kCCOptionECBMode,則默認即使CBC模式加密。
? ? ECB模式不是一種可靠安全的加密模式,推薦使用CBC模式。
? ? 另外也可以通過其他的庫或者方法實現(xiàn)GCM等方式的AES加密。在后面的代碼塊中翻入方法。
*/

4. 前三個步驟已經(jīng)完成了加密的基本算法代碼,接下來直接示例實現(xiàn)一個傳參加密:

- (NSString *)EncryptStringFromtServiceStartMap:(NSDictionary *)json {
    //補充ts字段。
    NSMutableDictionary *muJson = [NSMutableDictionary dictionaryWithDictionary:json];
    NSTimeInterval tsVal =  [[NSDate date] timeIntervalSince1970];
    [muJson setObject:[NSNumber numberWithInteger:(NSUInteger)(1000* tsVal)] forKey:@"ts"];
    NSString *jsonString = nil;
    NSError  *error;
    NSData   *jsonData = [NSJSONSerialization dataWithJSONObject:muJson
                                                         options:NSJSONWritingPrettyPrinted
                                                           error:&error];
    [self loadAESKeyAndIVData];//獲取key和iv。
    //進行AES加密。
    NSData *aesData =  aesCBCEncrypt(jsonData, self.aesSHA256keyData, self.aesIVData);
    
    //base64再次加密AES-CBC加密后的數(shù)據(jù)流,返回值作為start_service的參數(shù)
    NSString *base64 =  [aesData base64EncodedStringWithOptions:(NSDataBase64EncodingOptions)0];
    NSString *encryptStr = base64;
    NSLog(@"jsonContent:%@",muJson);
    NSLog(@"start_service參數(shù)encryptStr = %@",encryptStr);
    NSData *uncodeAESData = aesCBCDecrypt(aesData, self.aesSHA256keyData, self.aesIVData);
    if(uncodeAESData){
        NSError *error = nil;
        NSDictionary *uncodeDict = [NSJSONSerialization JSONObjectWithData:uncodeAESData options:kNilOptions error:&error];
        if (error) {
            NSString *uncodeJSON = [[NSString alloc] initWithData:uncodeAESData encoding:NSUTF8StringEncoding];
            if(uncodeJSON){
                NSLog(@"驗證解密ServiceMap:%@", uncodeJSON);
            }else{
                NSLog(@"驗證解密ServiceMap: 解析失?。?@", error);
            }
        } else {
            NSLog(@"驗證解密ServiceMap:%@",uncodeDict);
        }
    }
    return encryptStr;
}

//初始化AES加密的Key和iv向量數(shù)據(jù)。
- (void)loadAESKeyAndIVData {
    // 設置隨機種子為 4728423
    NSString *mt19937Str = JKJMT19937Seed(4728423);
    NSString *sha256Str = sha256String(mt19937Str);
    
    /*
     密鑰,截取sha256的64個字節(jié)前面32個字節(jié)
     IV:截取sha256的64個字節(jié)前面16個字節(jié)
     */
    NSString *keyString = substringWithLength(sha256Str, 32);
    NSString *ivString  = substringWithLength(sha256Str, 16);
    
    //獲取AES加密Key
    _aesSHA256keyData = [keyString dataUsingEncoding:NSUTF8StringEncoding];
    
    //獲取AES加密的IV向量
    _aesIVData = [ivString dataUsingEncoding:NSUTF8StringEncoding];
}

5. 歸納,完成4的操作,用到了一下兩個庫,a. C++中的random庫,實現(xiàn)mt19937隨機數(shù);b.?CommonCrypto庫,實現(xiàn)AES-CBC對稱加密,實現(xiàn)SHA256加密。c. 另外Base64是OC中的NSData(NSDataBase64Encoding)分類方法提供。

#include <random>

#import <CommonCrypto/CommonCrypto.h>

?6. 補充, AES加密如果需要GCM或者其它(非CBC、非ECB)模式的,可能需要用到如下的方法去實現(xiàn):a. 使用iOS13之后的庫, b. 使用第三方庫(libsodium-ios為例)

  • a.使用iOS13之后的庫代碼如下:
//
//  AESEncryptor.swift
//
//  Created by xw.long on 2024/4/7.
//

import Foundation
import CryptoKit
import CommonCrypto


@available(iOS 13.0, *)
@objc class AESEncryptor: NSObject {
    
    
    func encryptDataUsingCBCMode(data: Data, key: Data, iv: Data) -> Data? {
        let bufferSize = data.count + kCCBlockSizeAES128
        var buffer = [UInt8](repeating: 0, count: bufferSize)
        var numBytesEncrypted: size_t = 0
        
        let cryptStatus = data.withUnsafeBytes { dataBytes in
            key.withUnsafeBytes { keyBytes in
                iv.withUnsafeBytes { ivBytes in
                    CCCrypt(CCOperation(kCCEncrypt),
                            CCAlgorithm(kCCAlgorithmAES),
                            CCOptions(kCCOptionPKCS7Padding),
                            keyBytes.baseAddress, key.count,
                            ivBytes.baseAddress,
                            dataBytes.baseAddress, data.count,
                            &buffer, bufferSize,
                            &numBytesEncrypted)
                }
            }
        }
        
        if cryptStatus == kCCSuccess {
            return Data(buffer.prefix(Int(numBytesEncrypted)))
        } else {
            print("Error: \(cryptStatus)")
            return nil
        }
    }



    
    
    
    
    
    // 加密方法
    @objc func encrypt(content: String, key: String, iv: String) -> Data? {
        guard let keyData = Data(hexString: key),
              let ivData = Data(hexString: iv),
              let contentData = content.data(using: .utf8) else {
            print("AESEncryptor 無法將輸入轉換為Data")
            return nil
        }
        do {
            // 創(chuàng)建AES密鑰
            let aesKey = SymmetricKey(data: keyData)
            
            // 使用AES-256-GCM加密
            let sealedBox = try AES.GCM.seal(contentData, using: aesKey, nonce: AES.GCM.Nonce(data: ivData))
            
            // 返回加密后的數(shù)據(jù)
            return sealedBox.combined
        } catch {
            print("AESEncryptor 加密失敗: \(error)")
            return nil
        }
    }
    
    // 解密方法
    @objc func decrypt(encryptedData: Data, key: String, iv: String) -> String? {
        guard let keyData = Data(hexString: key),
              let ivData = Data(hexString: iv) else {
            print("AESEncryptor 無法將輸入轉換為Data")
            return nil
        }
        
        do {
            // 創(chuàng)建AES密鑰
            let aesKey = SymmetricKey(data: keyData)
            
            // 解密
            let sealedBox = try AES.GCM.SealedBox(combined: encryptedData)
            let decryptedData = try AES.GCM.open(sealedBox, using: aesKey)
            
            // 將解密后的數(shù)據(jù)轉換為字符串
            guard let decryptedString = String(data: decryptedData, encoding: .utf8) else {
                print("解密后的數(shù)據(jù)無法轉換為字符串")
                return nil
            }
            
            return decryptedString
        } catch {
            print("AESEncryptor 解密失敗: \(error)")
            return nil
        }
    }
    
    // 測試方法
    @objc static func test() {
        let content = "hello world"
        let key = "3891346e92151849d58e70de02a05c596b48afe1ae2bdeedf3e69c661c2ea2ae"
        let iv = "3891346e9215"
        
         if let encryptedData = AESEncryptor().encrypt(content: content, key: key, iv: iv) {
            print("AESEncryptor 加密后的數(shù)據(jù): \(encryptedData.base64EncodedString())")
            
            if let decryptedString = AESEncryptor().decrypt(encryptedData: encryptedData, key: key, iv: iv) {
                print("AESEncryptor 解密后的字符串: \(decryptedString)")
            }
        }
    }

}

// 十六進制字符串轉換為Data擴展
extension Data {
    init?(hexString: String) {
        var hexString = hexString
        var data = Data()
        
        while hexString.count > 0 {
            let subIndex = hexString.index(hexString.startIndex, offsetBy: 2)
            let hexChar = String(hexString[..<subIndex])
            hexString = String(hexString[subIndex...])
            
            guard let byte = UInt8(hexChar, radix: 16) else {
                return nil
            }
            
            data.append(byte)
        }
        
        self = data
    }
}


+ (void)swiftTest {
    NSString *originalString = @"3891346e92151849d89070de02a05c596b48a123ae2bdeedf3e69c661c2ea2ae";
    
    // 截取新的key和iv
    NSString *key = [originalString substringToIndex:32];
    NSString *iv = [originalString substringToIndex:12];
    
    // 待加密的內容
    NSString *content = @"hello world";
    
    // 調用加密方法
    if (@available(iOS 13.0, *)) {
        NSData *encryptedData = [[AESEncryptor new] encryptWithContent:content key:key iv:iv];
        // 將加密后的數(shù)據(jù)轉換為Base64字符串
        NSString *encryptedString = [encryptedData base64EncodedStringWithOptions:0];
        NSLog(@"加密后的字符串: %@", encryptedString);
    } else {
        // Fallback on earlier versions
    }
}


  • b. 使用第三方庫(libsodium-ios為例)

庫引用可以通過cocoa-pod方法,在Podfile文件中加入如下代碼,并在對應文件目錄下執(zhí)行【pod install】。

?platform :ios, '12.0'

也可以通過github 下載:https://github.com/mochtu/libsodium-ios

# Uncomment the next line to define a global platform for your project

?platform :ios, '12.0'

target 'MYPROJECT' do

? # Comment the next line if you don't want to use dynamic frameworks

? use_frameworks!

? # Pods for MYPROJECT

? pod 'libsodium-ios'

end

post_install do |pi|

? ? pi.pods_project.targets.each do |t|

? ? ? t.build_configurations.each do |config|

? ? ? ? config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.0'

? ? ? end

? ? end

end

下面是庫引入之后得代碼示例:文章來源地址http://www.zghlxwxcb.cn/news/detail-845482.html

#include <sodium.h>


NSData *encryptStringWithAES256EStream(NSString *inputString, const unsigned char *nonce, const unsigned char *key) {
    // 轉換輸入字符串為NSData
    NSData *inputData = [inputString dataUsingEncoding:NSUTF8StringEncoding];
    
    // 獲取輸入數(shù)據(jù)的長度
    NSUInteger inputLength = inputData.length;
    
    // 準備輸出緩沖區(qū)
    NSMutableData *encryptedData = [NSMutableData dataWithLength:inputLength];
    
    // 產(chǎn)生AES-256-ESTREAM流密碼
    unsigned char stream[inputLength];
    crypto_stream_aes256estream(stream, inputLength, nonce, key);
    
    // 對輸入數(shù)據(jù)進行異或運算,實現(xiàn)加密
    unsigned char *inputBytes = (unsigned char *)inputData.bytes;
    unsigned char *encryptedBytes = (unsigned char *)encryptedData.mutableBytes;
    for (NSUInteger i = 0; i < inputLength; i++) {
        encryptedBytes[i] = inputBytes[i] ^ stream[i];
    }
    
    return encryptedData;
}

+ (void)cryptoTest {
    // 初始化libsodium庫
    if (sodium_init() == -1) {
        NSLog(@"libsodium初始化失敗");
        return;
    }
    
    // 長度為16字節(jié)的nonce
    unsigned char nonce[crypto_stream_aes256estream_NONCEBYTES];
    randombytes_buf(nonce, sizeof(nonce));
    
    // 長度為32字節(jié)的密鑰
    unsigned char key[crypto_stream_aes256estream_KEYBYTES];
    randombytes_buf(key, sizeof(key));
    
    // 要加密的字符串
    NSString *inputString = @"hello world";
    
    // 使用AES-256-ESTREAM密鑰流對字符串進行加密
    NSData *encryptedData = encryptStringWithAES256EStream(inputString, nonce, key);

    // 打印加密后的數(shù)據(jù)
    NSLog(@"加密后的數(shù)據(jù):%@", encryptedData);
    
  }

到了這里,關于iOS MT19937隨機數(shù)生成,結合AES-CBC加密算法實現(xiàn)。的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 生成隨機數(shù)

    用于產(chǎn)生隨機數(shù) boolean nextBoolean() : 返回下一個偽隨機數(shù),它是取自此隨機數(shù)生成器序列的均勻分布的 boolean 值。 void nextBytes(byte[] bytes) : 生成隨機字節(jié)并將其置于用戶提供的 byte 數(shù)組中。 double nextDouble() : 返回下一個偽隨機數(shù),它是取自此隨機數(shù)生成器序列的、在 0.0 和 1.0 之

    2024年02月03日
    瀏覽(30)
  • Flutter 生成隨機數(shù)

    如何讓隨機數(shù)變化? 我們嘗試過的都知道,當你創(chuàng)建出來一個隨機數(shù)后,調用他他的值是隨機的,但是,這時候他的值就會固定住,不管怎么樣都是隨機出來的那個數(shù),如果想要他每次都不一樣的話,我們就想要使用刷新來讓他變化了。 我們可以使用這樣的方法來使他每次不一

    2024年02月13日
    瀏覽(21)
  • haiku生成隨機數(shù)

    Haiku 遵循 JAX 的設計,生成的隨機數(shù)是兩個元素組成的列表。其中第一個元素是用于生成偽隨機數(shù)的狀態(tài),第二個元素是用于分發(fā)密鑰的子鍵。兩個元素分別用于狀態(tài)和子鍵,確保在分布式計算或并行計算中,多個隨機數(shù)生成器的狀態(tài)可以在一定程度上相互影響,從而提高隨

    2024年01月20日
    瀏覽(27)
  • Hutool 生成隨機數(shù)和隨機字符串

    官方文檔: https://www.hutool.cn/docs/#/core/工具類/隨機工具-RandomUtil 整理完畢,完結撒花~

    2024年02月16日
    瀏覽(37)
  • 生成隨機數(shù)——C語言

    在C語言中,可以使用標準庫函數(shù) rand() 來生成隨機數(shù)。需要注意的是, rand() 函數(shù)生成的是偽隨機數(shù),具體的隨機序列取決于種子(seed)的值。 下面是一個簡單的示例代碼,展示如何在C語言中生成隨機數(shù): 在上述代碼中,首先包含了 stdio.h 、 stdlib.h 和 time.h 頭文件來使用相

    2024年02月12日
    瀏覽(31)
  • rust怎么生成隨機數(shù)?

    在 Rust 中,有幾種不同的方法可以實現(xiàn)隨機數(shù)生成。以下是其中幾種常見的方法,以及它們的優(yōu)缺點: 優(yōu)點: rand crate 是 Rust 中最常用的隨機數(shù)庫,提供了多種隨機數(shù)生成器和功能。它易于使用,并且具有廣泛的社區(qū)支持。 缺點: rand crate 生成的隨機數(shù)是偽隨機數(shù),可能不

    2024年02月14日
    瀏覽(31)
  • 【Linux】隨機數(shù)的生成

    【Linux】隨機數(shù)的生成

    /dev/random是一個隨機數(shù)生成器設備文件,用于生成高質量的隨機數(shù)。它通過收集系統(tǒng)上的環(huán)境噪聲(例如硬件噪聲,磁盤活動等)來產(chǎn)生隨機數(shù)。由于它只在系統(tǒng)上有足夠的環(huán)境噪聲時才能生成隨機數(shù),因此/dev/random生成的隨機數(shù)是高質量的。 但是,/dev/random的主要缺點是,如

    2024年02月11日
    瀏覽(20)
  • MySQL、Oracle 生成隨機ID、隨機數(shù)、隨機字符串

    MySQL、Oracle 生成隨機ID、隨機數(shù)、隨機字符串

    UUID():是由128位的數(shù)字組成的全局唯一標識符。每次都生成一個新的隨機數(shù)。 它通常以32個十六進制數(shù)的形式表示,分為5個部分,以連字符分隔。 UUID的長度是36個字符,包括32個十六進制數(shù)字和4個連字符。 UUID的標準格式是由 8-4-4-4-12 個十六進制數(shù)字組成的,其中每個部分的

    2024年01月16日
    瀏覽(29)
  • 【數(shù)電實驗】隨機數(shù)生成電路

    【數(shù)電實驗】隨機數(shù)生成電路

    1. 設計并實現(xiàn)一個隨機數(shù)生成電路,每 2 秒 隨機生成一個 0~999 之間的數(shù) 字,并在數(shù)碼管上顯示生成的隨機數(shù)。 2. 為系統(tǒng)設置一個復位鍵,復位后數(shù)碼管顯示“000”,2 秒后再開始每 2 秒 生成并顯示隨機數(shù),要求使用按鍵復位。 3. 實驗板上輸入時鐘選擇 1kHz 或更高的頻率。

    2024年02月08日
    瀏覽(23)
  • mysql 自動生成隨機數(shù)

    在MySQL中,生成隨機數(shù)可以使用`RAND()`函數(shù)。以下是一些基本用法: 1. **生成0到1之間的隨機浮點數(shù)**: ? ?```sql ? ?SELECT RAND(); ? ?``` 2. **生成指定范圍內的隨機整數(shù)**(例如,生成1到100之間的隨機整數(shù)): ? ?```sql ? ?SELECT FLOOR(RAND() * 100) + 1; ? ?``` ? ?這里,`RAND()`生成0到

    2024年01月22日
    瀏覽(20)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包