# 非对称密钥生成和转换规格

当前章节说明系统支持的算法及其对应规格。密钥生成指定规格的方式有两种：

*   字符串参数：以字符串的形式描述开发者需要生成的密钥规格。
    
*   密钥参数：使用密钥的详细密码学信息，构造密钥对象。
    

对于每种算法采用哪种方式，将会在具体的每个算法规格中介绍。

#### RSA

RSA（Rivest–Shamir–Adleman），当前支持使用字符串参数和密钥参数两种方式生成RSA密钥。

#### 使用字符串参数生成

以字符串参数生成RSA密钥，具体的“字符串参数”由“RSA密钥类型”和“素数个数”使用符号“|”拼接而成，用于在创建非对称密钥生成器时，指定密钥规格。

生成RSA非对称密钥时，默认素数为2，PRIMES\_2参数可省略。

| RSA密钥类型 | 素数个数 | 字符串参数 | API版本 |
| --- | --- | --- | --- |
| RSA512 | 2 | RSA512\|PRIMES_2 | 9+ |
| RSA768 | 2 | RSA768\|PRIMES_2 | 9+ |
| RSA1024 | 2 | RSA1024\|PRIMES_2 | 9+ |
| RSA1024 | 3 | RSA1024\|PRIMES_3 | 9+ |
| RSA2048 | 2 | RSA2048\|PRIMES_2 | 9+ |
| RSA2048 | 3 | RSA2048\|PRIMES_3 | 9+ |
| RSA3072 | 2 | RSA3072\|PRIMES_2 | 9+ |
| RSA3072 | 3 | RSA3072\|PRIMES_3 | 9+ |
| RSA4096 | 2 | RSA4096\|PRIMES_2 | 9+ |
| RSA4096 | 3 | RSA4096\|PRIMES_3 | 9+ |
| RSA4096 | 4 | RSA4096\|PRIMES_4 | 9+ |
| RSA8192 | 2 | RSA8192\|PRIMES_2 | 9+ |
| RSA8192 | 3 | RSA8192\|PRIMES_3 | 9+ |
| RSA8192 | 4 | RSA8192\|PRIMES_4 | 9+ |
| RSA8192 | 5 | RSA8192\|PRIMES_5 | 9+ |

使用同步接口生成RSA2048、RSA3072、RSA4096和RSA8192非对称密钥会增加耗时。

系统对主线程有时间限制，耗时较长会导致失败。建议生成大位数密钥时，使用异步接口或使用多线程并发能力。

创建RSA非对称密钥生成器时，若用于随机生成密钥，生成的RSA密钥规格与创建时指定的密钥规格一致；若用于密钥转换，生成的RSA密钥规格与转换时指定的密钥数据规格一致。

#### 使用密钥参数生成

从API version 10开始，支持使用密钥参数生成RSA密钥。

RSA密钥参数，涉及三个整数，包括：

*   n：模数（Modulus），是私钥和公钥的公共参数。
    
*   sk：私钥指数（privateExponent），公式中常写作d。
    
*   pk：公钥指数（publicExponent），公式中常写作e。
    

创建非对称密钥生成器时，支持根据指定的公钥和私钥参数生成RSA密钥，具体情况见下表：

*   √：表示需要指定这一列中的具体属性，来构成密钥参数。
    
*   ×：表示这一列中的具体属性对应某种密钥参数，但是当前不支持通过该密钥参数生成密钥。
    

| 参数名 | 公共参数 | 公钥参数 | 私钥参数 | 公私钥对参数 |
| --- | --- | --- | --- | --- |
| n | × | √ | × | √ |
| pk | N/A | √ | N/A | √ |
| sk | N/A | N/A | × | √ |

根据上表：

*   RSA不支持通过指定公共参数（n）来随机生成密钥。
    
*   RSA不支持通过指定私钥参数（n, sk）来生成私钥。
    

#### ECC

ECC（Elliptic Curve Cryptography），是一种基于椭圆曲线数学的公钥密码算法。

椭圆曲线算法可以看作是定义在特殊集合下数的运算，当前算法库支持的ECC密钥均为Fp域的椭圆曲线，p为素数，Fp域也称素数域。

支持使用字符串参数和密钥参数生成ECC密钥，还支持通过曲线名生成公共密钥参数。

#### 使用字符串参数生成

以字符串参数生成ECC密钥，具体的“字符串参数”由“非对称密钥算法”和“密钥长度”拼接而成，用于在创建非对称密钥生成器时，指定密钥规格。

| 非对称密钥算法 | 密钥长度（bit） | 曲线名 | 字符串参数 | API版本 |
| --- | --- | --- | --- | --- |
| ECC | 192 | NID_X9_62_prime192v1 | ECC192 | 26.0.0+ |
| ECC | 224 | NID_secp224r1 | ECC224 | 9+ |
| ECC | 256 | NID_X9_62_prime256v1 | ECC256 | 9+ |
| ECC | 384 | NID_secp384r1 | ECC384 | 9+ |
| ECC | 521 | NID_secp521r1 | ECC521 | 9+ |
| ECC | 160 | NID_brainpoolP160r1 | ECC_BrainPoolP160r1 | 11+ |
| ECC | 160 | NID_brainpoolP160t1 | ECC_BrainPoolP160t1 | 11+ |
| ECC | 192 | NID_brainpoolP192r1 | ECC_BrainPoolP192r1 | 11+ |
| ECC | 192 | NID_brainpoolP192t1 | ECC_BrainPoolP192t1 | 11+ |
| ECC | 224 | NID_brainpoolP224r1 | ECC_BrainPoolP224r1 | 11+ |
| ECC | 224 | NID_brainpoolP224t1 | ECC_BrainPoolP224t1 | 11+ |
| ECC | 256 | NID_brainpoolP256r1 | ECC_BrainPoolP256r1 | 11+ |
| ECC | 256 | NID_brainpoolP256t1 | ECC_BrainPoolP256t1 | 11+ |
| ECC | 320 | NID_brainpoolP320r1 | ECC_BrainPoolP320r1 | 11+ |
| ECC | 320 | NID_brainpoolP320t1 | ECC_BrainPoolP320t1 | 11+ |
| ECC | 384 | NID_brainpoolP384r1 | ECC_BrainPoolP384r1 | 11+ |
| ECC | 384 | NID_brainpoolP384t1 | ECC_BrainPoolP384t1 | 11+ |
| ECC | 512 | NID_brainpoolP512r1 | ECC_BrainPoolP512r1 | 11+ |
| ECC | 512 | NID_brainpoolP512t1 | ECC_BrainPoolP512t1 | 11+ |
| ECC | 256 | NID_secp256k1 | ECC_Secp256k1 | 14+ |

创建ECC非对称密钥生成器时，如果用于随机生成密钥，生成的ECC密钥规格与创建密钥生成器时指定的密钥规格一致。如果用于密钥转换，生成的ECC密钥规格与密钥转换时指定的密钥数据规格一致。

#### 使用密钥参数生成

从API version 10开始，支持使用密钥参数生成ECC密钥。

Fp域下的ECC密钥参数包括：

*   p：素数，用于确定Fp。
    
*   a, b：确定椭圆曲线的方程。
    
*   g：椭圆曲线的一个基点(base point)，可由gx，gy表示。
    
*   n：基点g的阶(order)。
    
*   h：余因子(cofactor)。
    
*   sk：私钥，是一个随机整数，小于n。
    
*   pk：公钥，是椭圆曲线上的一个点， pk = sk \* g。
    

创建非对称密钥生成器时，支持使用指定的公钥和私钥参数生成ECC密钥，具体情况见下表：

*   √：表示需要指定这一列中的具体属性，来构成密钥参数。

| 参数名 | 公共参数 | 公钥参数 | 私钥参数 | 公私钥对参数 |
| --- | --- | --- | --- | --- |
| fieldType | √ | √ | √ | √ |
| p | √ | √ | √ | √ |
| a | √ | √ | √ | √ |
| b | √ | √ | √ | √ |
| g | √ | √ | √ | √ |
| n | √ | √ | √ | √ |
| h | √ | √ | √ | √ |
| pk | N/A | √ | N/A | √ |
| sk | N/A | N/A | √ | √ |

*   当前ECC只支持Fp域，因此fieldType固定为"Fp"。fieldType和p构成了属性field，当前field只支持ECFieldFp。
    
*   g和pk为ECC曲线上的点，属于Point类型，需要指定具体的X和Y坐标。
    

#### 使用曲线名生成密钥参数

从API version 11开始，支持使用曲线名来生成ECC公共密钥参数。

*   曲线名为要求输入的字符串参数，支持的曲线名请参考ECC密钥字符串参数表中的“曲线名”一列。
    
*   生成的公共密钥参数可以直接用于随机生成公私钥，也可用于构造公钥、私钥及公私钥对密钥参数。
    

#### DSA

DSA（Digital Signature Algorithm），是一种基于模运算和整数有限域离散对数难题的公钥密码算法，常用于数字签名和验签，不能用于加解密。

当前支持使用字符串参数和密钥参数两种方式生成DSA密钥。

#### 约束与限制

使用同步接口生成DSA2048或DSA3072非对称密钥，或者处理明文长度超过2048位，会导致耗时增加。

系统对主线程有时间限制，耗时较长会导致失败。建议生成大位数密钥时，使用异步接口或使用多线程并发能力。

#### 使用字符串参数生成

使用字符串参数生成DSA密钥，具体的“字符串参数”由“非对称密钥算法”和“密钥长度”拼接而成，用于在创建非对称密钥生成器时，指定密钥规格。

| 非对称密钥算法 | 密钥长度（bit） | 字符串参数 | API版本 |
| --- | --- | --- | --- |
| DSA | 1024 | DSA1024 | 10+ |
| DSA | 2048 | DSA2048 | 10+ |
| DSA | 3072 | DSA3072 | 10+ |

使用同步接口生成DSA2048、DSA3072非对称密钥或明文长度超过2048位会导致耗时增加。

系统对主线程有时间限制，耗时较长会导致失败。建议生成大位数密钥时，使用异步接口或使用多线程并发能力。

创建的DSA非对称密钥生成器用于随机生成密钥时，生成的密钥规格与创建时指定的密钥规格一致。用于密钥转换时，生成的密钥规格与转换时指定的密钥数据规格一致。

#### 使用密钥参数生成

从API version 10开始支持，使用密钥参数生成DSA密钥。

DSA密钥参数，包括：

*   p：一个素模数，比特长度为64的整数倍。
    
*   q：p-1的素因子，长度与p的长度有关。
    
*   g：g = (h ^ ((p - 1) / q)) mod p，h为满足1 < h < p -1的任意整数。
    
*   sk：私钥，为随机生成的整数，满足0 < sk < q。
    
*   pk：公钥，pk = (g ^ sk) mod p。
    

当创建非对称密钥生成器时，支持根据指定的公钥和私钥参数生成DSA密钥，具体情况参见下表：

*   √：表示需要指定这一列中的具体属性，来构成密钥参数。
    
*   ×：表示这一列中的具体属性对应某种密钥参数，但是当前不支持通过该密钥参数生成密钥。
    

| 参数名 | 公共参数 | 公钥参数 | 私钥参数 | 公私钥对参数 |
| --- | --- | --- | --- | --- |
| p | √ | √ | × | √ |
| q | √ | √ | × | √ |
| g | √ | √ | × | √ |
| pk | N/A | √ | N/A | √ |
| sk | N/A | N/A | × | √ |

*   DSA不支持通过指定私钥参数（p, q, g, sk）来生成私钥。
    
*   当使用公共参数（p, q, g）来生成DSA密钥对时，DSA密钥长度至少需要1024位。
    

#### SM2

SM2是一种基于椭圆曲线的公钥密码算法，采用Fp域上的椭圆曲线。

当前支持使用字符串参数和密钥参数生成SM2密钥，并支持通过曲线名生成公共密钥参数。

#### 使用字符串参数生成

当前支持以字符串参数生成SM2密钥，具体的“字符串参数”由“非对称密钥算法”和“密钥长度”使用符号“\_”拼接而成，用于在创建非对称密钥生成器时，指定密钥规格。

| 非对称密钥算法 | 密钥长度（bit） | 曲线名 | 字符串参数 | API版本 |
| --- | --- | --- | --- | --- |
| SM2 | 256 | NID_sm2 | SM2_256 | 10+ |

#### 使用密钥参数生成

从API version 11开始，支持使用密钥参数生成SM2密钥。

Fp域下的SM2密钥参数包括：

*   p：素数，用于确定Fp。
    
*   a, b：确定椭圆曲线的方程。
    
*   g：椭圆曲线的一个基点(base point)，可由gx，gy表示。
    
*   n：基点g的阶(order)。
    
*   h：余因子(cofactor)。
    
*   sk：私钥，是一个随机整数，小于n。
    
*   pk：公钥，是椭圆曲线上的一个点，pk = sk \* g。
    

当创建非对称密钥生成器时，支持根据指定的公钥和私钥参数生成SM2密钥，具体支持情况如表所示：

*   √：表示需要指定这一列中的具体属性，来构成密钥参数。

| 参数名 | 公共参数 | 公钥参数 | 私钥参数 | 公私钥对参数 |
| --- | --- | --- | --- | --- |
| fieldType | √ | √ | √ | √ |
| p | √ | √ | √ | √ |
| a | √ | √ | √ | √ |
| b | √ | √ | √ | √ |
| g | √ | √ | √ | √ |
| n | √ | √ | √ | √ |
| h | √ | √ | √ | √ |
| pk | N/A | √ | N/A | √ |
| sk | N/A | N/A | √ | √ |

*   当前SM2只支持Fp域，因此fieldType固定为"Fp"。fieldType和p构成了属性field，当前field只支持ECFieldFp。
    
*   g和pk为SM2曲线上的点，属于Point类型，需要指定具体X，Y坐标。
    

#### 使用曲线名生成密钥参数

从API version 11开始，支持使用曲线名称生成SM2公钥参数。

*   曲线名为要求输入的字符串参数，支持的曲线名为"NID\_sm2"。
    
*   生成的公共密钥参数可以直接随机生成公私钥，也可用于构造公、私以及公私钥对密钥参数。
    

#### Ed25519

Ed25519算法是基于EdDSA算法的数字签名算法，密钥长度为256位，采用Edwards曲线实现。该算法不支持加解密，主要用于数字签名和验证。

当前支持使用字符串参数和密钥参数生成Ed25519密钥。

#### 使用字符串参数生成

使用字符串参数生成 Ed25519 密钥，以在创建非对称密钥生成器时指定密钥规格。

| 非对称密钥算法 | 字符串参数 | API版本 |
| --- | --- | --- |
| Ed25519 | Ed25519 | 11+ |

#### 使用密钥参数生成

从API version 11开始，支持使用密钥参数生成Ed25519密钥。

Ed25519密钥参数包括：

*   sk：私钥，一个 32 字节的随机值。
    
*   pk：公钥，一个 32 字节的值，从私钥派生而来。
    

当创建非对称密钥生成器时，支持根据指定的公钥和私钥参数生成Ed25519密钥，具体情况见下表：

*   √：表示需要指定这一列中的具体属性，来构成密钥参数。

| 参数名 | 公钥参数 | 私钥参数 | 公私钥对参数 |
| --- | --- | --- | --- |
| pk | √ | N/A | √ |
| sk | N/A | √ | √ |

Ed25519密钥参数没有公共参数，不支持通过公共参数生成密钥。

#### X25519

X25519算法是一种 Diffie-Hellman 密钥交换算法，用于密钥协商。

支持使用字符串参数和密钥参数生成X25519密钥。

#### 使用字符串参数生成

使用字符串参数生成X25519密钥，指定密钥规格。

| 非对称密钥算法 | 字符串参数 | API版本 |
| --- | --- | --- |
| X25519 | X25519 | 11+ |

#### 使用密钥参数生成

从API version 11开始支持使用密钥参数生成X25519密钥。

X25519密钥参数包括：

*   sk：私钥，一个 32 字节的随机值。
    
*   pk：公钥，一个 32 字节的值，从私钥派生而来。
    

当创建非对称密钥生成器时，指定公/私钥参数生成X25519密钥的支持情况如表所示。

*   √：表示需要指定这一列中的具体属性，来构成密钥参数。

| 参数名 | 公钥参数 | 私钥参数 | 公私钥对参数 |
| --- | --- | --- | --- |
| pk | √ | N/A | √ |
| sk | N/A | √ | √ |

X25519没有公共密钥参数，不支持通过公共参数生成密钥。

#### DH

DH（Diffie–Hellman key exchange），是一种密钥协商算法，只涉及公钥的交换，它可以提供前向安全性，即使在通信渠道被监听的情况下，也不会暴露双方的私钥。

支持使用字符串参数和密钥参数生成DH密钥，支持根据素数长度和私钥长度生成公共密钥参数。

#### 使用字符串参数生成

以字符串参数生成DH密钥，具体的“字符串参数”由“非对称密钥算法”和“知名安全素数群参数”使用符号“\_”拼接而成，用于在创建非对称密钥生成器时，指定密钥规格。

| 非对称密钥算法 | 知名安全素数群参数 | 密钥长度（bit） | 字符串参数 | API版本 |
| --- | --- | --- | --- | --- |
| DH | modp1536 | 1536 | DH_modp1536 | 11+ |
| DH | modp2048 | 2048 | DH_modp2048 | 11+ |
| DH | modp3072 | 3072 | DH_modp3072 | 11+ |
| DH | modp4096 | 4096 | DH_modp4096 | 11+ |
| DH | modp6144 | 6144 | DH_modp6144 | 11+ |
| DH | modp8192 | 8192 | DH_modp8192 | 11+ |
| DH | ffdhe2048 | 2048 | DH_ffdhe2048 | 11+ |
| DH | ffdhe3072 | 3072 | DH_ffdhe3072 | 11+ |
| DH | ffdhe4096 | 4096 | DH_ffdhe4096 | 11+ |
| DH | ffdhe6144 | 6144 | DH_ffdhe6144 | 11+ |
| DH | ffdhe8192 | 8192 | DH_ffdhe8192 | 11+ |

创建DH非对称密钥生成器时，如果用于随机生成密钥，生成的DH密钥规格与创建密钥生成器时指定的密钥规格一致；如果用于密钥转换，生成的DH密钥规格与密钥转换时指定的密钥数据规格一致。

#### 使用密钥参数生成

从API version 11开始支持使用密钥参数生成DH密钥。

DH密钥参数，包括：

*   p：一个足够大的素数，用作有限域的模数。它被所有通信双方共享。
    
*   g：g是DH算法的生成元，是素数p的原根。它被所有通信双方共享。
    
*   l：length，表示私钥长度，以bit为单位。当l为0时，代表不指定私钥长度。
    
*   sk：私钥，一个随机生成的私钥值。
    
*   pk：公钥，通过使用公共参数（p 和 g）和私钥进行计算得到。
    

当创建非对称密钥生成器时，对于指定公/私钥参数生成DH密钥的支持情况，如表所示。

*   √：表示需要指定这一列中的具体属性，来构成密钥参数。

| 参数名 | 公共参数 | 公钥参数 | 私钥参数 | 公私钥对参数 |
| --- | --- | --- | --- | --- |
| p | √ | √ | √ | √ |
| g | √ | √ | √ | √ |
| l | √ | √ | √ | √ |
| pk | N/A | √ | N/A | √ |
| sk | N/A | N/A | √ | √ |

#### 使用素数长度和私钥长度生成公共密钥参数

从API version 11开始，使用素数长度和私钥长度生成DH公共密钥参数。

如果素数长度与安全素数组的素数长度一致，则选用对应的知名安全素数群。对应关系如表所示。

| 素数长度（bit） | 知名安全素数群 |
| --- | --- |
| 2048 | ffdhe2048 |
| 3072 | ffdhe3072 |
| 4096 | ffdhe4096 |
| 6144 | ffdhe6144 |
| 8192 | ffdhe8192 |

*   素数p的比特长度必须大于等于512且小于等于10000。
    
*   私钥长度l为可选参数，默认为0，l值的设置范围需大于2\*(96+(素数p位数-1)/1024\*16)。
    
*   生成的公共密钥参数可以直接用于随机生成公私钥，也可以用于构造公钥、私钥或公私钥对。
    
*   生成非知名群的密钥参数耗时较长，建议优先选用知名安全素数群。