什么取代了 OpenSSL 3 中的 AES_set_decrypt_key 和 AES_unwrap_key?

问题描述 投票:0回答:1

OpenSSL 3 中已弃用

AES_set_decrypt_key
AES_unwrap_key
函数。我正在维护一个使用它们的函数,我想更新该函数以使用未弃用的函数:

std::unique_ptr<uint8_t[]> rfc3394_key_unwrap(const uint8_t* key, size_t key_len,
    const void *input, size_t input_len, const void *iv) noexcept 
{
  AES_KEY aes_key;
  AES_set_decrypt_key(key, key_len * 8, &aes_key);

  const int output_len = input_len - 8;

  auto out = std::make_unique<uint8_t[]>(output_len);

  const auto ret = AES_unwrap_key(&aes_key, (const uint8_t*)iv, out.get(),
                                  (const uint8_t*)input, input_len);

  if (ret != output_len) {
    return nullptr;
  }

  return out;
}

或者,如果您愿意,也可以使用 C 语言:

uint8_t* rfc3394_key_unwrap(const uint8_t *key, size_t key_len, const void *input,
    size_t input_len, const void *iv)
{
  AES_KEY aes_key;
  AES_set_decrypt_key(key, key_len * 8, &aes_key);

  const int output_len = input_len - 8;

  uint8_t* out = (uint8_t*) malloc(output_len);

  const intret = AES_unwrap_key(&aes_key, (const uint8_t*)iv, out,
                                (const uint8_t*)input, input_len);

  if (ret != output_len) {
    free(out);
    return NULL;
  }

  return out;
}

我无法确定替换内容是什么(可能在

EVP_CIPHER
函数中?)。我应该寻找什么?

c++ c openssl aes
1个回答
0
投票

看来 OpenSSL 文档几乎完全没有涵盖这一点。

OpenSSL 3.0 迁移指南
中唯一提到
AES_wrap_key()
AES_unwrap_key()的是:

  • AES_unwrap_key()、AES_wrap_key()

请参阅 “已弃用的低级加密函数”

尽管如此,在编写此答案时,弃用低级加密函数部分省略了任何提及

AES_wrap_key()
AES_unwrap_key()
的内容。

但是,AES_wrap_key()

AES_unwrap_key()
 的当前(截至 2024 年 10 月 15 日)OpenSSL 源代码是

/* * Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ /* * AES_encrypt/AES_decrypt are deprecated - but we need to use them to implement * these functions */ #include "internal/deprecated.h" #include "internal/cryptlib.h" #include <openssl/aes.h> #include <openssl/modes.h> int AES_wrap_key(AES_KEY *key, const unsigned char *iv, unsigned char *out, const unsigned char *in, unsigned int inlen) { return CRYPTO_128_wrap(key, iv, out, in, inlen, (block128_f) AES_encrypt); } int AES_unwrap_key(AES_KEY *key, const unsigned char *iv, unsigned char *out, const unsigned char *in, unsigned int inlen) { return CRYPTO_128_unwrap(key, iv, out, in, inlen, (block128_f) AES_decrypt); }

CRYPTO_128_wrap()

OpenSSL源代码有这样的评论:

/** Wrapping according to RFC 3394 section 2.2.1.
因此您需要进行 RFC 3394 密钥包装/解包。

OpenSSL 演示代码提供了

密钥包装/解开示例。尽管没有明确引用 RFC 3394。

相关包装代码看起来

/* Create a context for the encrypt operation */ if ((ctx = EVP_CIPHER_CTX_new()) == NULL) goto err; EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW); /* Fetch the cipher implementation */ if ((cipher = EVP_CIPHER_fetch(libctx, "AES-256-WRAP", propq)) == NULL) goto err; /* * Initialise an encrypt operation with the cipher/mode, key and IV. * We are not setting any custom params so let params be just NULL. */ if (!EVP_EncryptInit_ex2(ctx, cipher, wrap_key, wrap_iv, /* params */ NULL)) goto err; /* Encrypt plaintext */ if (!EVP_EncryptUpdate(ctx, outbuf, &outlen, wrap_pt, sizeof(wrap_pt))) goto err; /* Finalise: there can be some additional output from padding */ if (!EVP_EncryptFinal_ex(ctx, outbuf + outlen, &tmplen)) goto err; outlen += tmplen;
我怀疑你必须使用 

"AES-128-WRAP"

 而不是 
"AES-256-WRAP"

然后是

EVP_aes_128_wrap()

 
cipher,它明确提到了 RFC 3394:

    EVP_aes_128_wrap()、EVP_aes_192_wrap()、EVP_aes_256_wrap()、EVP_aes_128_wrap_pad()、EVP_aes_192_wrap_pad()、EVP_aes_256_wrap_pad()
使用 128、192 和 256 位密钥的 AES 密钥包装,分别根据 RFC 3394 第 2.2.1 节(“包装”)和 RFC 5649 第 4.1 节(“带填充包装”)。

我怀疑使用该方法的方法是将 OpenSSL 演示代码中对

EVP_CIPHER_fetch()

 的调用替换为对 
EVP_aes_128_wrap()
 的调用。

© www.soinside.com 2019 - 2024. All rights reserved.