2013-11-28 80 views
0

我想爲一些使用Crypto ++庫的加密操作做一個Objective-C包裝類。我有幾個問題,如何從NSData對象獲取密鑰到Crypto ++的密鑰/ iv數組中?

這是我使用

- (void)testSerpentEncryptonMechanism 
{ 
    byte key[ CryptoPP::Serpent::MAX_KEYLENGTH ], iv[ CryptoPP::Serpent::BLOCKSIZE ]; 

    ::memset(key, 0x50 , CryptoPP::Serpent::MAX_KEYLENGTH); 
    ::memset(iv, 0x10, CryptoPP::Serpent::BLOCKSIZE); 

    NSString *andThisShalBeEncrypted = @"Serpentine and black..."; 

    NSLog(@"will encrypt %@",andThisShalBeEncrypted); 

    NSString *encrypted = [self encryptWithSerpentString:andThisShalBeEncrypted withKey:key]; 

    NSLog(@"encrypted:%@",encrypted); 

    NSString *decrypted = [self decryptWithSerpentString:encrypted withKey:key andIV:iv]; 

    NSLog(@"decrypted: %@",decrypted); 


} 

- (NSString *)encryptWithSerpentString:(NSString *)plaintext withKey:(byte[])keyArray 
{ 
    std::string ptext = [plaintext UTF8String]; 
    std::string ciphertext; 

    byte key[ CryptoPP::Serpent::MAX_KEYLENGTH ], iv[ CryptoPP::Serpent::BLOCKSIZE ]; 

    ::memset(key, 0x50 , CryptoPP::Serpent::MAX_KEYLENGTH); 
    ::memset(iv, 0x10, CryptoPP::Serpent::BLOCKSIZE); 

    CryptoPP::Serpent::Encryption serpentEncryptor (key, CryptoPP::Serpent::MAX_KEYLENGTH); 
    CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcSerpentEncryptor (serpentEncryptor, iv); 

    CryptoPP::StreamTransformationFilter stfSerpentEncryptor(cbcSerpentEncryptor, new CryptoPP::StringSink (ciphertext)); 
    stfSerpentEncryptor.Put(reinterpret_cast<const unsigned char*>(ptext.c_str()), ptext.length() + 1); 
    stfSerpentEncryptor.MessageEnd(); 

    std::string finalCT; 
    CryptoPP::StringSource base64Encoder (ciphertext, true, new CryptoPP::Base64Encoder(new CryptoPP::StringSink(finalCT))); 



    return @(finalCT.c_str()); 
} 

- (NSString *)decryptWithSerpentString:(NSString *)ciphertext withKey:(byte[])keyArray andIV:(byte[])initializationVector 
{ 
    std::string ctext; 
    std::string plaintext; 

    byte key[ CryptoPP::Serpent::MAX_KEYLENGTH ], iv[ CryptoPP::Serpent::BLOCKSIZE ]; 

// ::memset(key, &keyArray , CryptoPP::Serpent::MAX_KEYLENGTH); 
// ::memset(iv, (byte[])initializationVector, CryptoPP::Serpent::BLOCKSIZE); 

    ::memset(key, 0x50 , CryptoPP::Serpent::MAX_KEYLENGTH); 
    ::memset(iv, 0x10, CryptoPP::Serpent::BLOCKSIZE); 

    // decode from base64 
    std::string encoded = [ciphertext UTF8String]; 
    CryptoPP::StringSource base64Encoder (encoded, true, new CryptoPP::Base64Decoder(new CryptoPP::StringSink(ctext))); 


    CryptoPP::Serpent::Decryption serpentDecryptor (key, CryptoPP::Serpent::MAX_KEYLENGTH); 
    CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcSerpentDecryptor (serpentDecryptor, iv); 

    CryptoPP::StreamTransformationFilter stfSerpentDecryptor(cbcSerpentDecryptor, new CryptoPP::StringSink (ctext));// crash 
    stfSerpentDecryptor.Put(reinterpret_cast<const unsigned char*>(ctext.c_str()), ctext.length() + 1); 
    stfSerpentDecryptor.MessageEnd(); 


    return @(ctext.c_str()); 
} 

1中的代碼)我如何通過鑰匙/ IV作爲方法參數?同類型CryptoPP的:: InvalidCiphertext未捕獲的異常終止:StreamTransformationFilter試圖decrpyt

的libC++ abi.dylib時見註釋代碼,還是不行......

2)我得到一個崩潰:密文長度不是塊大小的倍數

爲什麼?我認爲解密是自動的,並且加密將相應地填充明文... 我還想爲方法添加一個HMAC ...這將在加密之後添加並在解密之前進行檢查,對嗎?

+0

想知道爲什麼你選擇了「蛇」。 – zaph

+0

非常高的安全邊際... – user1028028

+0

有趣。剛剛與我的Crypto領域專家進行了覈對:AES是一個更好的選擇,也是非傳統使用的轉向選擇。 3DES需要DES兼容性時。我認爲你的專家有一個很好的選擇蛇的理由。 – zaph

回答

2

要獲得填充,您必須自己動手或使用支持標準填充(如PKCS7)的API。基本加密,流密碼除外,都是基於塊的,在較低的層次上必須有完整的塊。一些更高級別的API提供了填充。

我傳遞密鑰iv和數據as NSData *並訪問字節data.bytes
Cypher的輸出數據:

NSMutableData *dataOut = [NSMutableData dataWithLength:dataIn.length + kCCBlockSizeAES128]; 
// ... 
        dataOut.mutableBytes, 
        dataOut.length, 
        &cryptBytes 
// ... 
dataOut.length = cryptBytes; 

我會讓我的API調用類似:

- (NSString *)encryptWithSerpentText:(NSString *)text key:(NSData *)key iv:(NSData *)iv; 

Mac電腦是好的,但你將如何進行驗證。最好研究認證的最佳實踐。

對於HMAC,只需使用Apple提供的CommonCrypto庫。 CommonCrypto還支持:AES128,DES,3DES,CAST,RC4和Blowfish,但不是蛇。

最後,爲了讓事情能夠記錄服務器和客戶端中的每一步,這樣就可以找到因錯誤數據而失敗的步驟。在這種情況下,針對混合Objective-C/C++版本的直接C++版本。

+0

Well Cryo ++正在進行填充...但是,當我得到解密方法時,它似乎缺少了......我認爲這與UTF8String有關...... – user1028028

+0

if我做key = keyData.bytes;我得到'數組類型不可分配'... – user1028028

+0

對於使用NSData和加密的[示例](http://stackoverflow.com/a/19930185/451475)。 – zaph