【问题标题】:How to use a custom key in Crypto++如何在 Crypto++ 中使用自定义密钥
【发布时间】:2015-02-05 04:42:16
【问题描述】:

我有一个关于这个问题中的加密代码的问题: Crypto++ encrypt and decrypt in two different c++ programs

如果我想使用自定义键/iv,我该怎么做?

【问题讨论】:

    标签: c++ encryption key crypto++ passphrase


    【解决方案1】:

    如果我想使用自定义键/iv,我该怎么做?

    只需将其插入具有模式的密码即可。有很多模式可供选择,但您应该使用经过身份验证的加密模式,如 EAX、CCM 或 GCM。有关 Crypto++ 中模式的讨论,请参阅 Category:Mode

    下面的代码采用密码或秘密,键入密码,然后对消息进行加密和编码。接下来,它对加密的消息进行解码。最后它会打印一些参数。


    try {
    
        // KDF parameters
        string password = "Super secret password";
        unsigned int iterations = 15000;
        char purpose = 0; // unused by Crypto++
    
        // 32 bytes of derived material. Used to key the cipher.
        //   16 bytes are for the key, and 16 bytes are for the iv.
        SecByteBlock derived(32);
    
        // KDF function
        PKCS5_PBKDF2_HMAC<SHA256> kdf;
        kdf.DeriveKey(derived.data(), derived.size(), purpose, (byte*)password.data(), password.size(), NULL, 0, iterations);
    
        // Encrypt a secret message
        string plaintext = "Attack at dawn", ciphertext, recovered;
    
        // Key the cipher
        EAX<AES>::Encryption encryptor;
        encryptor.SetKeyWithIV(derived.data(), 16, derived.data() + 16, 16);
    
        AuthenticatedEncryptionFilter ef(encryptor, new StringSink(ciphertext));
        ef.Put((byte*)plaintext.data(), plaintext.size());
        ef.MessageEnd();
    
        // Key the cipher
        EAX<AES>::Decryption decryptor;
        decryptor.SetKeyWithIV(derived.data(), 16, derived.data() + 16, 16);
    
        AuthenticatedDecryptionFilter df(decryptor, new StringSink(recovered));
        df.Put((byte*)ciphertext.data(), ciphertext.size());
        df.MessageEnd();
    
        // Done with encryption and decryption
    
        // Encode various parameters
        HexEncoder encoder;
        string key, iv, cipher;
    
        encoder.Detach(new StringSink(key));
        encoder.Put(derived.data(), 16);
        encoder.MessageEnd();
    
        encoder.Detach(new StringSink(iv));
        encoder.Put(derived.data() + 16, 16);
        encoder.MessageEnd();
    
        encoder.Detach(new StringSink(cipher));
        encoder.Put((byte*)ciphertext.data(), ciphertext.size());
        encoder.MessageEnd();
    
        // Print stuff
        cout << "plaintext: " << plaintext << endl;
        cout << "key: " << key << endl;
        cout << "iv: " << iv << endl;
        cout << "ciphertext: " << cipher << endl;
        cout << "recovered: " << recovered << endl;
    
    }
    catch(CryptoPP::Exception& ex)
    {
        cerr << ex.what() << endl;
    }
    

    程序的运行会产生以下输出。

    $ ./cryptopp-test.exe
    plaintext: Attack at dawn
    key: 7A8C7732898FB687669CB7DBEFBDD789
    iv: 0AA980BABE72797E415C9B8979BF30EF
    ciphertext: 197D0BD1A12577393AD1B1696B75D0FC6B8A142CF15B5F887AA965CE75F0
    recovered: Attack at dawn
    

    更好的是,使用集成加密方案。 Crypto++ 提供了其中的两个。第一个是Elliptic Curve Integrated Encryption Scheme,它在椭圆诅咒域上运行。第二个是Discrete Logarithm Integrated Encryption Scheme,作用于整数域。

    它的“更好”有很多不明显的原因,但最大的原因是它的IND-CCA2。其他更实用的包括:您不能重用安全上下文,因为系统内置了正确使用;并且删除了填充,这大大简化了证明并避免了潜在的预言。该系统还基于Discrete Logs,这使其成为基于 Diffie-Hellman 的问题,并且被认为在任何地方都很难。

    【讨论】:

    • 非常感谢您的回答。我想用 C# 应用程序解密密文。如果我将使用您的解决方案加密明文,我希望我可以使用标准方法对其进行解密。我稍后会测试它...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-07
    • 2017-10-27
    • 2018-01-09
    • 2017-06-22
    • 2023-04-06
    • 2017-10-04
    相关资源
    最近更新 更多