Extend PBE code to support non default PKCS#5 v2.0 PRFs.
This commit is contained in:
parent
76240b3a39
commit
856640b54f
9 changed files with 190 additions and 65 deletions
3
CHANGES
3
CHANGES
|
@ -4,6 +4,9 @@
|
|||
|
||||
Changes between 0.9.8b and 0.9.9 [xx XXX xxxx]
|
||||
|
||||
*) Initial support for PKCS#5 v2.0 PRFs other than default SHA1 HMAC.
|
||||
[Steve Henson]
|
||||
|
||||
*) Replace the algorithm specific calls to generate keys in "req" with the
|
||||
new API.
|
||||
[Steve Henson]
|
||||
|
|
|
@ -799,8 +799,20 @@ void PKCS5_PBE_add(void);
|
|||
|
||||
int EVP_PBE_CipherInit (ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
|
||||
ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de);
|
||||
|
||||
/* PBE type */
|
||||
|
||||
/* Can appear as the outermost AlgorithmIdentifier */
|
||||
#define EVP_PBE_TYPE_OUTER 0x0
|
||||
/* Is an PRF type OID */
|
||||
#define EVP_PBE_TYPE_PRF 0x1
|
||||
|
||||
int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, int md_nid,
|
||||
EVP_PBE_KEYGEN *keygen);
|
||||
int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
|
||||
EVP_PBE_KEYGEN *keygen);
|
||||
int EVP_PBE_find(int type, int pbe_nid,
|
||||
int *pcnid, int *pmnid, EVP_PBE_KEYGEN **pkeygen);
|
||||
void EVP_PBE_cleanup(void);
|
||||
|
||||
#define ASN1_PKEY_ALIAS 0x1
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* project 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
* Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
|
@ -67,71 +67,135 @@ static STACK *pbe_algs;
|
|||
|
||||
/* Setup a cipher context from a PBE algorithm */
|
||||
|
||||
typedef struct {
|
||||
int pbe_nid;
|
||||
const EVP_CIPHER *cipher;
|
||||
const EVP_MD *md;
|
||||
EVP_PBE_KEYGEN *keygen;
|
||||
} EVP_PBE_CTL;
|
||||
typedef struct
|
||||
{
|
||||
int pbe_type;
|
||||
int pbe_nid;
|
||||
int cipher_nid;
|
||||
int md_nid;
|
||||
EVP_PBE_KEYGEN *keygen;
|
||||
} EVP_PBE_CTL;
|
||||
|
||||
int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
|
||||
ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de)
|
||||
{
|
||||
{
|
||||
const EVP_CIPHER *cipher;
|
||||
const EVP_MD *md;
|
||||
int cipher_nid, md_nid;
|
||||
EVP_PBE_KEYGEN *keygen;
|
||||
|
||||
EVP_PBE_CTL *pbetmp, pbelu;
|
||||
int i;
|
||||
pbelu.pbe_nid = OBJ_obj2nid(pbe_obj);
|
||||
if (pbelu.pbe_nid != NID_undef) i = sk_find(pbe_algs, (char *)&pbelu);
|
||||
else i = -1;
|
||||
|
||||
if (i == -1) {
|
||||
if (!EVP_PBE_find(EVP_PBE_TYPE_OUTER, OBJ_obj2nid(pbe_obj),
|
||||
&cipher_nid, &md_nid, &keygen))
|
||||
{
|
||||
char obj_tmp[80];
|
||||
EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_PBE_ALGORITHM);
|
||||
if (!pbe_obj) BUF_strlcpy (obj_tmp, "NULL", sizeof obj_tmp);
|
||||
else i2t_ASN1_OBJECT(obj_tmp, sizeof obj_tmp, pbe_obj);
|
||||
ERR_add_error_data(2, "TYPE=", obj_tmp);
|
||||
return 0;
|
||||
}
|
||||
if(!pass) passlen = 0;
|
||||
else if (passlen == -1) passlen = strlen(pass);
|
||||
pbetmp = (EVP_PBE_CTL *)sk_value (pbe_algs, i);
|
||||
i = (*pbetmp->keygen)(ctx, pass, passlen, param, pbetmp->cipher,
|
||||
pbetmp->md, en_de);
|
||||
if (!i) {
|
||||
}
|
||||
|
||||
if(!pass)
|
||||
passlen = 0;
|
||||
else if (passlen == -1)
|
||||
passlen = strlen(pass);
|
||||
|
||||
if (cipher_nid == -1)
|
||||
cipher = NULL;
|
||||
else
|
||||
cipher = EVP_get_cipherbynid(cipher_nid);
|
||||
|
||||
if (md_nid == -1)
|
||||
md = NULL;
|
||||
else
|
||||
md = EVP_get_digestbynid(md_nid);
|
||||
|
||||
if (!keygen(ctx, pass, passlen, param, cipher, md, en_de))
|
||||
{
|
||||
EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_KEYGEN_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pbe_cmp(const char * const *a, const char * const *b)
|
||||
{
|
||||
{
|
||||
const EVP_PBE_CTL * const *pbe1 = (const EVP_PBE_CTL * const *) a,
|
||||
* const *pbe2 = (const EVP_PBE_CTL * const *)b;
|
||||
return ((*pbe1)->pbe_nid - (*pbe2)->pbe_nid);
|
||||
}
|
||||
int ret = (*pbe1)->pbe_type - (*pbe2)->pbe_type;
|
||||
if (ret)
|
||||
return ret;
|
||||
else
|
||||
return (*pbe1)->pbe_nid - (*pbe2)->pbe_nid;
|
||||
}
|
||||
|
||||
/* Add a PBE algorithm */
|
||||
|
||||
int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
|
||||
int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, int md_nid,
|
||||
EVP_PBE_KEYGEN *keygen)
|
||||
{
|
||||
{
|
||||
EVP_PBE_CTL *pbe_tmp;
|
||||
if (!pbe_algs) pbe_algs = sk_new(pbe_cmp);
|
||||
if (!(pbe_tmp = (EVP_PBE_CTL*) OPENSSL_malloc (sizeof(EVP_PBE_CTL)))) {
|
||||
if (!pbe_algs)
|
||||
pbe_algs = sk_new(pbe_cmp);
|
||||
if (!(pbe_tmp = (EVP_PBE_CTL*) OPENSSL_malloc (sizeof(EVP_PBE_CTL))))
|
||||
{
|
||||
EVPerr(EVP_F_EVP_PBE_ALG_ADD,ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
pbe_tmp->pbe_nid = nid;
|
||||
pbe_tmp->cipher = cipher;
|
||||
pbe_tmp->md = md;
|
||||
}
|
||||
pbe_tmp->pbe_type = pbe_type;
|
||||
pbe_tmp->pbe_nid = pbe_nid;
|
||||
pbe_tmp->cipher_nid = cipher_nid;
|
||||
pbe_tmp->md_nid = md_nid;
|
||||
pbe_tmp->keygen = keygen;
|
||||
|
||||
|
||||
sk_push (pbe_algs, (char *)pbe_tmp);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
|
||||
EVP_PBE_KEYGEN *keygen)
|
||||
{
|
||||
int cipher_nid, md_nid;
|
||||
if (cipher)
|
||||
cipher_nid = EVP_CIPHER_type(cipher);
|
||||
else
|
||||
cipher_nid = -1;
|
||||
if (md)
|
||||
md_nid = EVP_MD_type(md);
|
||||
else
|
||||
md_nid = -1;
|
||||
|
||||
return EVP_PBE_alg_add_type(EVP_PBE_TYPE_OUTER, nid,
|
||||
cipher_nid, md_nid, keygen);
|
||||
}
|
||||
|
||||
int EVP_PBE_find(int type, int pbe_nid,
|
||||
int *pcnid, int *pmnid, EVP_PBE_KEYGEN **pkeygen)
|
||||
{
|
||||
EVP_PBE_CTL *pbetmp, pbelu;
|
||||
int i;
|
||||
if (pbe_nid == NID_undef)
|
||||
return 0;
|
||||
pbelu.pbe_type = type;
|
||||
pbelu.pbe_nid = pbe_nid;
|
||||
i = sk_find(pbe_algs, (char *)&pbelu);
|
||||
if (i == -1)
|
||||
return 0;
|
||||
pbetmp = (EVP_PBE_CTL *)sk_value (pbe_algs, i);
|
||||
if (pcnid)
|
||||
*pcnid = pbetmp->cipher_nid;
|
||||
if (pmnid)
|
||||
*pmnid = pbetmp->md_nid;
|
||||
if (pkeygen)
|
||||
*pkeygen = pbetmp->keygen;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void EVP_PBE_cleanup(void)
|
||||
{
|
||||
{
|
||||
sk_pop_free(pbe_algs, OPENSSL_freeFunc);
|
||||
pbe_algs = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,6 +97,7 @@ EVP_PBE_alg_add(NID_pbeWithSHA1AndRC2_CBC, EVP_rc2_64_cbc(), EVP_sha1(),
|
|||
#endif
|
||||
#ifndef OPENSSL_NO_HMAC
|
||||
EVP_PBE_alg_add(NID_pbes2, NULL, NULL, PKCS5_v2_PBE_keyivgen);
|
||||
EVP_PBE_alg_add_type(EVP_PBE_TYPE_PRF, NID_hmacWithSHA1, -1, NID_sha1, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* project 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
* Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
|
@ -71,28 +71,36 @@
|
|||
#endif
|
||||
|
||||
/* This is an implementation of PKCS#5 v2.0 password based encryption key
|
||||
* derivation function PBKDF2 using the only currently defined function HMAC
|
||||
* with SHA1. Verified against test vectors posted by Peter Gutmann
|
||||
* derivation function PBKDF2.
|
||||
* SHA1 version verified against test vectors posted by Peter Gutmann
|
||||
* <pgut001@cs.auckland.ac.nz> to the PKCS-TNG <pkcs-tng@rsa.com> mailing list.
|
||||
*/
|
||||
|
||||
int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
|
||||
int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
|
||||
const unsigned char *salt, int saltlen, int iter,
|
||||
const EVP_MD *digest,
|
||||
int keylen, unsigned char *out)
|
||||
{
|
||||
unsigned char digtmp[SHA_DIGEST_LENGTH], *p, itmp[4];
|
||||
int cplen, j, k, tkeylen;
|
||||
{
|
||||
unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4];
|
||||
int cplen, j, k, tkeylen, mdlen;
|
||||
unsigned long i = 1;
|
||||
HMAC_CTX hctx;
|
||||
|
||||
mdlen = EVP_MD_size(digest);
|
||||
|
||||
HMAC_CTX_init(&hctx);
|
||||
p = out;
|
||||
tkeylen = keylen;
|
||||
if(!pass) passlen = 0;
|
||||
else if(passlen == -1) passlen = strlen(pass);
|
||||
while(tkeylen) {
|
||||
if(tkeylen > SHA_DIGEST_LENGTH) cplen = SHA_DIGEST_LENGTH;
|
||||
else cplen = tkeylen;
|
||||
if(!pass)
|
||||
passlen = 0;
|
||||
else if(passlen == -1)
|
||||
passlen = strlen(pass);
|
||||
while(tkeylen)
|
||||
{
|
||||
if(tkeylen > mdlen)
|
||||
cplen = mdlen;
|
||||
else
|
||||
cplen = tkeylen;
|
||||
/* We are unlikely to ever use more than 256 blocks (5120 bits!)
|
||||
* but just in case...
|
||||
*/
|
||||
|
@ -100,20 +108,22 @@ int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
|
|||
itmp[1] = (unsigned char)((i >> 16) & 0xff);
|
||||
itmp[2] = (unsigned char)((i >> 8) & 0xff);
|
||||
itmp[3] = (unsigned char)(i & 0xff);
|
||||
HMAC_Init_ex(&hctx, pass, passlen, EVP_sha1(), NULL);
|
||||
HMAC_Init_ex(&hctx, pass, passlen, digest, NULL);
|
||||
HMAC_Update(&hctx, salt, saltlen);
|
||||
HMAC_Update(&hctx, itmp, 4);
|
||||
HMAC_Final(&hctx, digtmp, NULL);
|
||||
memcpy(p, digtmp, cplen);
|
||||
for(j = 1; j < iter; j++) {
|
||||
HMAC(EVP_sha1(), pass, passlen,
|
||||
digtmp, SHA_DIGEST_LENGTH, digtmp, NULL);
|
||||
for(k = 0; k < cplen; k++) p[k] ^= digtmp[k];
|
||||
}
|
||||
for(j = 1; j < iter; j++)
|
||||
{
|
||||
HMAC(digest, pass, passlen,
|
||||
digtmp, mdlen, digtmp, NULL);
|
||||
for(k = 0; k < cplen; k++)
|
||||
p[k] ^= digtmp[k];
|
||||
}
|
||||
tkeylen-= cplen;
|
||||
i++;
|
||||
p+= cplen;
|
||||
}
|
||||
}
|
||||
HMAC_CTX_cleanup(&hctx);
|
||||
#ifdef DEBUG_PKCS5V2
|
||||
fprintf(stderr, "Password:\n");
|
||||
|
@ -125,7 +135,15 @@ int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
|
|||
h__dump (out, keylen);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
|
||||
const unsigned char *salt, int saltlen, int iter,
|
||||
int keylen, unsigned char *out)
|
||||
{
|
||||
return PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, EVP_sha1(),
|
||||
keylen, out);
|
||||
}
|
||||
|
||||
#ifdef DO_TEST
|
||||
main()
|
||||
|
@ -155,6 +173,8 @@ int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
|
|||
PBE2PARAM *pbe2 = NULL;
|
||||
const EVP_CIPHER *cipher;
|
||||
PBKDF2PARAM *kdf = NULL;
|
||||
const EVP_MD *prfmd;
|
||||
int prf_nid, hmac_md_nid;
|
||||
|
||||
if (param == NULL || param->type != V_ASN1_SEQUENCE ||
|
||||
param->value.sequence == NULL) {
|
||||
|
@ -226,10 +246,23 @@ int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
|
|||
goto err;
|
||||
}
|
||||
|
||||
if(kdf->prf && (OBJ_obj2nid(kdf->prf->algorithm) != NID_hmacWithSHA1)) {
|
||||
if (kdf->prf)
|
||||
prf_nid = OBJ_obj2nid(kdf->prf->algorithm);
|
||||
else
|
||||
prf_nid = NID_hmacWithSHA1;
|
||||
|
||||
if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, prf_nid, NULL, &hmac_md_nid, 0))
|
||||
{
|
||||
EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
prfmd = EVP_get_digestbynid(hmac_md_nid);
|
||||
if (prfmd == NULL)
|
||||
{
|
||||
EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if(kdf->salt->type != V_ASN1_OCTET_STRING) {
|
||||
EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
|
||||
|
@ -241,7 +274,8 @@ int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
|
|||
salt = kdf->salt->value.octet_string->data;
|
||||
saltlen = kdf->salt->value.octet_string->length;
|
||||
iter = ASN1_INTEGER_get(kdf->iter);
|
||||
PKCS5_PBKDF2_HMAC_SHA1(pass, passlen, salt, saltlen, iter, keylen, key);
|
||||
PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, prfmd,
|
||||
keylen, key);
|
||||
EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de);
|
||||
OPENSSL_cleanse(key, keylen);
|
||||
PBKDF2PARAM_free(kdf);
|
||||
|
|
|
@ -62,12 +62,12 @@
|
|||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#define NUM_NID 802
|
||||
#define NUM_SN 798
|
||||
#define NUM_LN 798
|
||||
#define NUM_OBJ 760
|
||||
#define NUM_NID 803
|
||||
#define NUM_SN 799
|
||||
#define NUM_LN 799
|
||||
#define NUM_OBJ 761
|
||||
|
||||
static unsigned char lvalues[5345]={
|
||||
static unsigned char lvalues[5353]={
|
||||
0x00, /* [ 0] OBJ_undef */
|
||||
0x2A,0x86,0x48,0x86,0xF7,0x0D, /* [ 1] OBJ_rsadsi */
|
||||
0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, /* [ 7] OBJ_pkcs */
|
||||
|
@ -828,6 +828,7 @@ static unsigned char lvalues[5345]={
|
|||
0x2A,0x85,0x03,0x02,0x09,0x01,0x03,0x03, /* [5320] OBJ_id_GostR3411_94_with_GostR3410_94_cc */
|
||||
0x2A,0x85,0x03,0x02,0x09,0x01,0x03,0x04, /* [5328] OBJ_id_GostR3411_94_with_GostR3410_2001_cc */
|
||||
0x2A,0x85,0x03,0x02,0x09,0x01,0x08,0x01, /* [5336] OBJ_id_GostR3410_2001_ParamSet_cc */
|
||||
0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x06, /* [5344] OBJ_hmacWithMD5 */
|
||||
};
|
||||
|
||||
static ASN1_OBJECT nid_objs[NUM_NID]={
|
||||
|
@ -2122,6 +2123,7 @@ static ASN1_OBJECT nid_objs[NUM_NID]={
|
|||
{"id-GostR3410-2001-ParamSet-cc",
|
||||
"GOST R 3410-2001 Parameter Set Cryptocom",
|
||||
NID_id_GostR3410_2001_ParamSet_cc,8,&(lvalues[5336]),0},
|
||||
{"hmacWithMD5","hmacWithMD5",NID_hmacWithMD5,8,&(lvalues[5344]),0},
|
||||
};
|
||||
|
||||
static ASN1_OBJECT *sn_objs[NUM_SN]={
|
||||
|
@ -2372,6 +2374,7 @@ static ASN1_OBJECT *sn_objs[NUM_SN]={
|
|||
&(nid_objs[784]),/* "gost89" */
|
||||
&(nid_objs[757]),/* "gost94" */
|
||||
&(nid_objs[797]),/* "gost94cc" */
|
||||
&(nid_objs[802]),/* "hmacWithMD5" */
|
||||
&(nid_objs[163]),/* "hmacWithSHA1" */
|
||||
&(nid_objs[432]),/* "holdInstructionCallIssuer" */
|
||||
&(nid_objs[430]),/* "holdInstructionCode" */
|
||||
|
@ -3186,6 +3189,7 @@ static ASN1_OBJECT *ln_objs[NUM_LN]={
|
|||
&(nid_objs[509]),/* "generationQualifier" */
|
||||
&(nid_objs[601]),/* "generic cryptogram" */
|
||||
&(nid_objs[99]),/* "givenName" */
|
||||
&(nid_objs[802]),/* "hmacWithMD5" */
|
||||
&(nid_objs[163]),/* "hmacWithSHA1" */
|
||||
&(nid_objs[486]),/* "homePostalAddress" */
|
||||
&(nid_objs[473]),/* "homeTelephoneNumber" */
|
||||
|
@ -4094,6 +4098,7 @@ static ASN1_OBJECT *obj_objs[NUM_OBJ]={
|
|||
&(nid_objs[ 3]),/* OBJ_md2 1 2 840 113549 2 2 */
|
||||
&(nid_objs[257]),/* OBJ_md4 1 2 840 113549 2 4 */
|
||||
&(nid_objs[ 4]),/* OBJ_md5 1 2 840 113549 2 5 */
|
||||
&(nid_objs[802]),/* OBJ_hmacWithMD5 1 2 840 113549 2 6 */
|
||||
&(nid_objs[163]),/* OBJ_hmacWithSHA1 1 2 840 113549 2 7 */
|
||||
&(nid_objs[37]),/* OBJ_rc2_cbc 1 2 840 113549 3 2 */
|
||||
&(nid_objs[ 5]),/* OBJ_rc4 1 2 840 113549 3 4 */
|
||||
|
|
|
@ -1075,6 +1075,10 @@
|
|||
#define LN_md5_sha1 "md5-sha1"
|
||||
#define NID_md5_sha1 114
|
||||
|
||||
#define LN_hmacWithMD5 "hmacWithMD5"
|
||||
#define NID_hmacWithMD5 802
|
||||
#define OBJ_hmacWithMD5 OBJ_rsadsi,2L,6L
|
||||
|
||||
#define LN_hmacWithSHA1 "hmacWithSHA1"
|
||||
#define NID_hmacWithSHA1 163
|
||||
#define OBJ_hmacWithSHA1 OBJ_rsadsi,2L,7L
|
||||
|
|
|
@ -799,3 +799,4 @@ id_GostR3410_2001_cc 798
|
|||
id_GostR3411_94_with_GostR3410_94_cc 799
|
||||
id_GostR3411_94_with_GostR3410_2001_cc 800
|
||||
id_GostR3410_2001_ParamSet_cc 801
|
||||
hmacWithMD5 802
|
||||
|
|
|
@ -338,6 +338,7 @@ rsadsi 2 2 : MD2 : md2
|
|||
rsadsi 2 4 : MD4 : md4
|
||||
rsadsi 2 5 : MD5 : md5
|
||||
: MD5-SHA1 : md5-sha1
|
||||
rsadsi 2 6 : : hmacWithMD5
|
||||
rsadsi 2 7 : : hmacWithSHA1
|
||||
rsadsi 3 2 : RC2-CBC : rc2-cbc
|
||||
: RC2-ECB : rc2-ecb
|
||||
|
|
Loading…
Reference in a new issue