Generate an RSA key pair and save as two key files.
[Superseded by RSA_MakeKeysXtd
.]
Public Declare Function RSA_MakeKeys Lib "diCrPKI.dll"
(ByVal strPubKeyFile As String, ByVal strPvkKeyFile As String,
ByVal nBits As Long, ByVal nExpFermat As Long, ByVal nTests As Long,
ByVal nCount As Long,
ByVal strPassword As String,
ByVal strSeed As String, ByVal nSeedLen As Long,
ByVal nOptionFlags As Long) As Long
nRet = RSA_MakeKeys(strPublicKeyFile, strPrivateKeyFile, nBits, nExpFermat,
nTests, nCount, strPassword,
strSeed, nSeedLen, nOptionFlags)
long __stdcall RSA_MakeKeys(const char *szPubKeyFile, const char *szEpkFile, long nBits, long nExpFermat, long nTests, long nCount, const char *szPassword, const void *lpSeed, long nSeedLen, long nOptions);
"pbeWithSHAAnd3-KeyTripleDES-CBC"
(default)"pkcs5PBES2"
plus one ofdes-EDE3-CBC
(default)AES128-CBC
AES192-CBC
AES256-CBC
If successful, the return value is zero; otherwise it returns a nonzero error code.
Public Function rsaMakeKeys
(szPubKeyFile As String, szPriKeyFile As String, szPassword As String, nBits As Long, Optional nExpFermat As Long = PKI_RSAEXP_EQ_65537, Optional szParams As String = "", Optional nOptions As Long = 0) As Long
Rsa.MakeKeys Method (String, String, Int32, Rsa.PublicExponent, Int32, String, Rsa.PbeOptions, Boolean, Byte[])
Rsa.MakeKeys Method (String, String, Int32, Rsa.PublicExponent, Int32, String, CipherAlgorithm, HashAlgorithm, Rsa.Format, Boolean)
static int dipki::Rsa::MakeKeys (const std::string &publicKeyFile, const std::string &privateKeyFile, const std::string &password, int nbits, PublicExponent exponent=PublicExponent::Exp_EQ_65537, PbeScheme pbes=PbeScheme::Default, const std::string ¶mString="", Format fileFormat=Format::Binary, bool showProgress=false)
The RSA key is stored by default as a pair of DER-encoded binary files.
The public and private keys are encoded into ASN.1 values of type
RSAPublicKey
and RSAPrivateKey
respectively (defined in PKCS #1).
The private key is then encrypted and encoded into a PKCS #8 EncryptedPrivateKeyInfo
type.
Any existing files of the same names will be overwritten without warning.
The key length must be greater than 96 bits. The value of the exponent is limited to the five values listed.
The password and iteration count are used to encrypt the private key according to the
specified PBE algorithm specified in nOptionFlags.
The password should be a string of ASCII characters and must not contain any NUL characters (i.e. Chr(0)
).
The seed is optional and is used to supplement the seeding of the random number generator.
The user may use the seed to provide some additional value ("user-supplied entropy") that is unique when the
keys are being generated.
See Random Number Generator and Seeds for more information.
The default format for the files is binary DER-encoded format.
Use either the PKI_KEY_FORMAT_PEM or the PKI_KEY_FORMAT_SSL flag to save in
base64 "PEM" format. Files saved with the PKI_KEY_FORMAT_SSL flag should be compatible
with OpenSSL. For more details on the formats, see
RSA_SavePublicKey()
and RSA_SaveEncPrivateKey()
.
Generating RSA key pairs can take some time. On a 1GHz P3 test machine, the following times were typical:
Key size | Time |
---|---|
512 | < 1 second |
1024 | 5 seconds |
2048 | 1 minute |
4096 | 6 minutes |
8192 | 1 hour |
Some programs like Office Access will get bored waiting for the longer processes to finish and may hang.
Setting the PKI_KEYGEN_INDICATE
flag will show progress in a separate console window (actually two, one for
p and one for q). Having a console window show progress will keep the parent application happy.
A dot "." indicates a new candidate is being tested,
and an asterisk "*" indicates that a Rabin-Miller test has been carried
out (that is the expensive part of the process). The program will close these console windows down automatically.
Do not use the PKI_KEYGEN_INDICATE
option in a multi-threaded environment.
For console-based programs, this option just shows the progress in the standard output.
Caution: pressing Ctrl-C or Ctrl-Break in the console window will kill your entire process altogether; that is, abort your whole application, which may not be what you want.
There is a very, very small possibility that the generator may fail to find a suitable prime number candidate
within the number of iterations it carries out. If this happens (we've never seen it, but it could in theory), the function
will return a KEYGEN_FAILED_ERROR
error code 24. This in itself does not indicate a
systemic problem with the Toolkit, just an incredibly unlucky event. Let us know if it happens more than once.
Dim nRet As Long Dim sPublicKeyFile As String Dim sPrivateKeyFile As String Dim sPassword As String sPublicKeyFile = "mykey.pub" sPrivateKeyFile = "mykey.p8e" sPassword = "password" ' Create a new pair of RSA keys saved as BER-encoded files Debug.Print "About to create a new RSA key pair..." nRet = RSA_MakeKeys(sPublicKeyFile, sPrivateKeyFile, 512, _ PKI_RSAEXP_EQ_3, 50, 1000, sPassword, "", 0, 0) Debug.Print "RSA_MakeKeys returns " & nRet & " (expected 0)"
The example above will generate a 512-bit RSA key pair and store in two files, a public key file mykey.pub
and an encrypted private key file mykey.p8e
. The exponent will be 3.
Rabin-Miller tests will be carried out 50 times to verify that the values of p and q are prime.
The private key will be encrypted using the default "pbeWithSHAAnd3-KeyTripleDES-CBC"
algorithm using the password
"password" and an iteration count of 1000.
strSeed = "yyyseed345"
nRet = RSA_MakeKeys(sPublicKeyFile, sPrivateKeyFile, 2048,
PKI_RSAEXP_EQ_65537, 64, 3000, "94tMhvTr7gvVy48q", strSeed, Len(strSeed),
PKI_PBE_PBKDF2_AES128)
The second example generates a 2048-bit RSA key pair with the exponent 65537 (0x10001). Sixty-four Rabin-Miller tests are used to test for primality. The private key will be encrypted using the PBES2 algorithm with AES-128 as the encryption scheme, the password "94tMhvTr7gvVy48q", and an iteration count of 3000. The string "yyyseed345" will be added to the RNG seeding process. Note the use of PKI_PBE_PBKDF2_AES128 as a replacement for the older (but still valid) option PKI_PBE_PBES2+PKI_BC_AES128.
RSA_ReadEncPrivateKey RSA_ReadPublicKey RSA_SaveEncPrivateKey RSA_SavePublicKey