什么决定了不同加密算法中的 BIGNUM 大小?

What determines the BIGNUM size in different crypto algorithms?

我玩 OpenSSL。 我看到不同的 openssl 类型使用 BIGNUM 类型。

例如:

  1. DSA 签名
typedef struct DSA_SIG_st {
    BIGNUM *r;
    BIGNUM *s;
} DSA_SIG;
  1. ECDSA 签名
typedef struct ECDSA_SIG_st {
    BIGNUM *r;
    BIGNUM *s;
} ECDSA_SIG;
  1. 椭圆曲线私钥
struct ec_key_st {
    int version;
    EC_GROUP *group;
    EC_POINT *pub_key;
    BIGNUM *priv_key;
    unsigned int enc_flag;
    point_conversion_form_t conv_form;
    int references;
    int flags;
    EC_EXTRA_DATA *method_data;
} /* EC_KEY */ ;
  1. RSA 结构
struct rsa_st {
    /*
     * The first parameter is used to pickup errors where this is passed
     * instead of aEVP_PKEY, it is set to 0
     */
    int pad;
    long version;
    const RSA_METHOD *meth;
    /* functional reference if 'meth' is ENGINE-provided */
    ENGINE *engine;
    BIGNUM *n;
    BIGNUM *e;
    BIGNUM *d;
    BIGNUM *p;
    BIGNUM *q;
    BIGNUM *dmp1;
    BIGNUM *dmq1;
    BIGNUM *iqmp;
    /* be careful using this if the RSA structure is shared */
    CRYPTO_EX_DATA ex_data;
    int references;
    int flags;
    /* Used to cache montgomery values */
    BN_MONT_CTX *_method_mod_n;
    BN_MONT_CTX *_method_mod_p;
    BN_MONT_CTX *_method_mod_q;
    /*
     * all BIGNUM values are actually in the following data, if it is not
     * NULL
     */
    char *bignum_data;
    BN_BLINDING *blinding;
    BN_BLINDING *mt_blinding;
};

BIGNUM 在 OpenSSL 中是:

struct bignum_st {
    BN_ULONG *d;                /* Pointer to an array of 'BN_BITS2' bit
                                 * chunks. */
    int top;                    /* Index of last used d +1. */
    /* The next are internal book keeping for bn_expand. */
    int dmax;                   /* Size of the d array. */
    int neg;                    /* one if the number is negative */
    int flags;
};

我不明白如何为特定算法选择 bignum 以及 bignum 数组的大小如何?

首先你没有自己分配实际的bn->d值; BN_* 例程为您完成,redo/change 根据需要完成。对于非过时版本的 OpenSSL,这些结构(以及几乎所有其他结构)是不透明的,您根本无法直接访问它们,尽管我可以理解想要了解它们。

对于使用数字(而不仅仅是位模式)的加密算法,您使用的数字取决于算法。对于 RSA,请参阅 the wikipedia article and if the PKCS1 link to RSA Labs no longer works (post EMC and Dell) use the stable IETF duplicates RFCs 2313, 2437, 4347, 8047 instead. There are other standards for RSA from ANSI/X9 and ISO, but they are less used and not significantly different. For DSA see again wikipedia and the (free) FIPS. For ECDSA you can see paid X9.62 or free SEC1 from SECG,但实际上它只是 DSA 对(大)class Weierstrass 形式椭圆曲线的直接改编。对于 DSA 和 ECDSA,出现在签名中的值是计算出来的,从未被挑选出来,尽管它们 受到每个操作的随机数 k 的影响,随机数 k 可以而且通常是随机地,均匀地挑选的在 [1, n-1] 中,其中 n 是子组阶数(大小)。请注意,对于最常用于 ECDSA 的 'prime' 曲线,如 P-256 和 P-384,曲线的设计使得子组阶数等于曲线阶数,这又接近但不等于基础素数场的模数。但是,这是那些特定曲线的 属性,而不是一般的 ECDSA 或 ECC。

在实践中,所有算法的密钥都应该通过直接调用适当的密钥生成函数或使用 EVP_PKEY_* API 生成(在 OpenSSL 中),或者从其他一些导入通过正确实施的过程生成它们的软件或系统。类似地,签名应该通过直接或通过 EVP 调用签名函数来创建,或者从其他正确创建它们的东西接收。所有 OpenSSL 代码都是免费的(语音和啤酒),因此您可以查看它并了解它的作用;有些人(包括我)发现至少有时在具有良好源代码级调试器的系统中编译此类代码并逐步查看它的作用是有帮助的。

标准警告:如果你只是想玩加密,或者像 OpenSSL 这样的特定实现,那就把自己搞砸了。如果您打算编写旨在提供安全性的软件,请不要通过猜测或反复试验来完成;要么使用由知道自己在做什么的人编写的(现有)软件,要么雇用或咨询这些人。它是 非常 易于编写 'security' 的软件,看似可以工作并通过测试但实际上是不安全的,而且(与您不同)真正了解该主题并知道如何发现这些缺陷将成为您或您用户的敌人。