这些答案都不构成任何形式的合理加密。
您真正想要做的是使用某种形式的经过身份验证的加密,以及某种形式的安全密钥派生算法。我个人的推荐是libsodium。它提供了非常好的默认值,以及一个相对不易出错的 API。
有几种不同的方法可以做到这一点:
- 使用随机密钥Authenticated Encryption 进行密钥加密
- 使用从密码短语Key Derivation 派生的密钥进行密钥加密
- 使用密钥协议的混合加密。 Public Key Encryption
所有这些可能性都集成到 libsodium 中,并且相对容易实现。
以下代码示例直接取自libsodium documentation。
对于 1:
#define MESSAGE ((const unsigned char *) "test")
#define MESSAGE_LEN 4
#define CIPHERTEXT_LEN (crypto_secretbox_MACBYTES + MESSAGE_LEN)
unsigned char nonce[crypto_secretbox_NONCEBYTES];
unsigned char key[crypto_secretbox_KEYBYTES];
unsigned char ciphertext[CIPHERTEXT_LEN];
/* Generate a secure random key and nonce */
randombytes_buf(nonce, sizeof nonce);
randombytes_buf(key, sizeof key);
/* Encrypt the message with the given nonce and key, putting the result in ciphertext */
crypto_secretbox_easy(ciphertext, MESSAGE, MESSAGE_LEN, nonce, key);
unsigned char decrypted[MESSAGE_LEN];
if (crypto_secretbox_open_easy(decrypted, ciphertext, CIPHERTEXT_LEN, nonce, key) != 0) {
/* If we get here, the Message was a forgery. This means someone (or the network) somehow tried to tamper with the message*/
}
对于 2:(从密码中导出密钥)
#define PASSWORD "Correct Horse Battery Staple"
#define KEY_LEN crypto_secretbox_KEYBYTES
unsigned char salt[crypto_pwhash_SALTBYTES];
unsigned char key[KEY_LEN];
/* Choose a random salt */
randombytes_buf(salt, sizeof salt);
if (crypto_pwhash
(key, sizeof key, PASSWORD, strlen(PASSWORD), salt,
crypto_pwhash_OPSLIMIT_INTERACTIVE, crypto_pwhash_MEMLIMIT_INTERACTIVE,
crypto_pwhash_ALG_DEFAULT) != 0) {
/* out of memory */
}
现在,key-array 包含一个适合在上面的代码示例中使用的键。我们没有使用randombytes_buf(key, sizeof key) 生成随机密钥,而是从用户定义的密码中生成了一个密钥,并将其用于加密。
3 是 3 种类型中“最复杂的”。如果您有两方通信,这就是您使用的。每一方都生成一个“密钥对”,其中包含一个公共密钥和一个秘密密钥。使用这些密钥对,他们可以共同商定一个“共享密钥”,他们可以使用该密钥对彼此加密(和签名)数据:
#define MESSAGE (const unsigned char *) "test"
#define MESSAGE_LEN 4
#define CIPHERTEXT_LEN (crypto_box_MACBYTES + MESSAGE_LEN)
unsigned char alice_publickey[crypto_box_PUBLICKEYBYTES];
unsigned char alice_secretkey[crypto_box_SECRETKEYBYTES];
crypto_box_keypair(alice_publickey, alice_secretkey);
unsigned char bob_publickey[crypto_box_PUBLICKEYBYTES];
unsigned char bob_secretkey[crypto_box_SECRETKEYBYTES];
crypto_box_keypair(bob_publickey, bob_secretkey);
unsigned char nonce[crypto_box_NONCEBYTES];
unsigned char ciphertext[CIPHERTEXT_LEN];
randombytes_buf(nonce, sizeof nonce);
if (crypto_box_easy(ciphertext, MESSAGE, MESSAGE_LEN, nonce,
bob_publickey, alice_secretkey) != 0) {
/* error */
}
unsigned char decrypted[MESSAGE_LEN];
if (crypto_box_open_easy(decrypted, ciphertext, CIPHERTEXT_LEN, nonce,
alice_publickey, bob_secretkey) != 0) {
/* message for Bob pretending to be from Alice has been forged! */
}
此代码首先生成两个密钥对(通常,这将分别发生在 bob 和 alice 的机器上,他们将相互发送他们的 public 密钥,同时保持他们的密钥,嗯,秘密)。
然后,随机生成一个随机数,并且对crypto_box_easy(...) 的调用加密了一条从 alice 到 bob 的消息(使用 bob 的公钥进行加密,并使用 alice 的密钥进行签名)。
然后(在可能通过网络发送消息之后),对crypto_box_open_easy(...) 的调用被 bob 用于解密消息(使用他自己的密钥进行解密,并使用 alice 的公钥来验证签名)。如果由于某种原因(有人试图篡改)消息验证失败,则由非零返回码指示。