140 likes | 266 Vues
This document by Magnus Nyström and Gareth Richards provides a comprehensive overview of Microsoft CryptoAPI objects, procedures, and mechanisms for retrieving One-Time Passwords (OTPs). It addresses the needs of applications that require interoperable access to connected OTP tokens, improving user experience and simplifying vendor requirements. The design focuses on HMAC approaches and outlines the key functions and parameters necessary for generating, importing, and exporting OTP keys, as well as defining standard OTP algorithm profiles like CALG_SECURID and CALG_HOTP, ensuring a better integration with CryptoAPI.
E N D
OTP-CryptoAPI Magnus Nyström & Gareth Richards, RSA Security 24 May 2005
Overview • Describes general Microsoft CryptoAPI objects, procedures and mechanisms that can be used to retrieve OTPs • Intended to meet the needs of applications wishing to access connected OTP tokens in an interoperable manner • Eases the task for vendors of OTP-consuming applications • Enables a better user experience
CryptoAPI Principles of Operation • Intent is to follow the HMAC approach for CryptoAPI • CryptAcquireContext gives handle to key container • CryptCreateHash gives handle to key object, specifies OTP mechanism • CryptSetHashParam sets parameters (uses PKCS #11 structures) • CryptHashData generates OTPs • CryptGetHashParam retrieves the OTP value CryptAcquireContext CryptCreateHash CryptSetHashParam CryptHashData CryptGetHashParam
Current Design • Cryptographic Service Providers supporting the described mechanism are identified as being of type PROV_OTP • OTP algorithms will be of class CALG_CLASS_OTP • Keys currently created through CryptGenKey and CryptSetKeyParam, with parameters borrowed from the PKCS #11 sibling document
OTP Algorithm Profiles • Initial draft defines two OTP algorithms • CALG_SECURID • CALG_SECURID_TRADITIONAL • In correspondence, one additional OTP algorithm is suggested • CALG_HOTP • For CALG_SECURID and CALG_SECURID_TRADITIONAL, the document defines the parameters that may be used in calls to CryptSetHashParam
PKCS #11 vs. “pure” CryptoAPI approach Seems preferable to make document standalone from OTP-PKCS11 Easier to gain acceptance from CryptoAPI community Requires CryptoAPI definitions of key parameters (attributes) What PKCS #11 key attributes would have to be represented as CryptoAPI key parameters? Probably no need for PP_PARAMS due to KP_ALGID For Discussion
PKCS #11 Key Attributes vs. CryptoAPI Key Parameters • CKA_END_DATE (SYSTEMTIME?) • CKA_VALUE_LEN (KP_KEYLEN?) • CKA_SERIAL_NUMBER (BYTE *) • CKA_OTP_FORMAT (DWORD) • CKA_OTP_LENGTH (DWORD) • CKA_OTP_PINPAD (BOOL) • CKA_OTP_APP_BASED (BOOL) • CKA_OTP_{CHALLENGE, TIME, COUNTER}_MODE (DWORD) • CKA_OTP_DEFAULT_PIN{_ALLOWED, _SET} (BOOL) • CKA_OTP_SERVICE_IDENTIFIER (LPCTSTR) • CKA_OTP_TIME_INTERVAL (DWORD) • CKA_OTP_ACCEPT_{TIME, COUNTER} (BOOL) • CKA_OTP_COUNTER_VALUE (BYTE *)
Importing an OTP Key HCRYPTKEY ImportHOTPKEY( HCRYPTPROV hProv, HCRTYPKEY hUnwrapKey, // Required for SIMPLEBLOB BYTE *blob, // SIMPLEBLOB or PLAINTEXTBLOB DWORD blobLen, BYTE *serialNumber, DWORD serialNumberLen, SYSTEMTIME expiryDate { HCRYPTKEY hOTPKey = (HCRYPTKEY)NULL; BOOL bTrue = TRUE; ALG_ID algID = CALG_HOTP; // Import the OTP key. CryptImportKey(hProv, blob, blobLen, hUnwrapKey, 0, &hOTPKey); // Set the key attributes CryptSetKeyParam(hOTPKey, KP_SERIAL_NUMBER, serialNumber, serialNumberLen, 0); CryptSetKeyParam(hOTPKey, KP_END_DATE, expiryDate, sizeof(expiryDate), 0); CryptSetKeyParam(hOTPKey, KP_OTP_COUNTER_MODE, &bTrue, sizeof(bTrue), 0); // Enable the key. CryptSetKeyParam(hOTPKey, KP_ALGID, algID, sizeof(algID), 0); return hOTPKey; }
Exporting an OTP Key BOOL ExportHOTPKey( HCRYPTKEY hOTPKey HCRTYPKEY hwrapKey, BYTE *blob, // Buffer to receive SIMPLEBLOB DWORD *blobLen { return CryptExportKey(hOTPKey, hWrapKey, SIMPLEBLOB, 0, blob, blobLen); }
Generating an OTP Key HCRYPTKEY GenerateSecurIDKey( HCRYPTPROV hProv, BYTE *serialNumber, DWORD serialNumberLen, SYSTEMTIME *expiryDate { HCRYPTKEY hOTPKey =(HCRYPTKEY)NULL; BOOL bTrue = TRUE; ALG_ID algID = CALG_SECURID; // Generate the OTP key. CryptGenKey(hProv, algID, CRYPT_EXPORTABLE, &hOTPKey); // Set the key attributes. CryptSetKeyParam(hOTPKey, KP_SERIAL_NUMBER, serialNumber, serialNumberLen, 0); CryptSetKeyParam(hOTPKey, KP_END_DATE, expiryDate, sizeof(SYSTEMTIME), 0); CryptSetKeyParam(hOTPKey, KP_OTP_TIME_MODE, &bTrue, sizeof(bTrue), 0); //Enable the key. CryptSetKeyParam(hOTPKey, KP_ALGID, algID, sizeof(algID), 0); return hOTPKey; }
Retrieving an OTP void GetOTP( HCRYPTPROV hProv, HCRYPTKEY hOTPKey, // Can be NULL to use default key. wchar_t *pPIN, BYTE *buf, DWORD *bufLen ) { HCRYPTHASH hHash = (HCRYPTHASH)NULL; SECURID_PARAMS securIDParams = {0}; securIDParams.flags = 0; securIDParams.pPIN = pin; securIDParams.applicationID = NULL; securIDParams.pReserved = NULL; CryptCreateHash(hProv, CALG_SECURID, hOTPKey, 0, hHash); CryptSetHashParam(hHash, HP_OTP_PARAM, &securIDParams, sizeof(securIDParams), 0); CryptHashData(hHash, NULL, 0, 0); CryptGetHashParam(hHash, HP_HASHVAL, buf, bufLen, 0); CryptDestroyHash(hHash); }
Importing OTP Key & Retrieving OTP // Acquire handle to target container. CryptAcquireContext (&hProv, pszContainer, pszProvider, PROV_OTP, 0); // Open handle to wrapping key to unwrap OTP key. CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hUnwrapKey); // Import the OTP key. hOTPKey = ImportSecurIDKey (hProv, hUnwrapKey, blob, blobLen, serialNumber, serialNumberLen, &expiryDate); // Generate an OTP from the new key. GetOTP (hProv, hOTPKey, pPIN, buf, &bufLen); CryptDestroyKey(hOTPKey); CryptDestroyKey(hUnwrapKey) CryptReleaseContext(hProv, 0);
Next Steps • Agreement and stabilization of document content • Preferably new draft within next 3 – 4 weeks, reflecting workshop discussions • Additional draft versions expected to be required • Possible future contribution of document? • Would preferably be “adopted” by Microsoft • Need Microsoft recognition of at least: PROV_OTP, ALG_CLASS_OTP • Preferably also the key parameters and the algorithm identifiers • Ideally, our definitions and structures would be part of CRYPTOAPI.H