Notes
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Le chiffrement en bloc et les clés MAC sont dérivés d’une clé principale , mais peuvent inclure d’autres sources en fonction du protocole et de la suite de chiffrement utilisée.
Le processus de dérivation de clés MAC et de chiffrement en bloc est le même pour le client et le serveur :
- Le moteur de protocole appelle CryptSetKeyParam sur la clé principale une ou plusieurs fois pour fournir l’fournisseur de solutions Cloud avec les informations nécessaires pour générer les clés.
- Étant donné que les clés CryptoAPI ne peuvent pas être dérivées directement d’autres clés, un objet de hachage est créé à partir de la clé principale à l’aide de CryptCreateHash. Ce hachage est utilisé pour créer les nouvelles clés.
- Les deux clés de chiffrement en bloc et les deux clés MAC sont créées à partir de l’objet « master hash » à l’aide de quatre appels à CryptDeriveKey.
Notes
Lorsque vous effectuez des reconnectations SSL, un moteur de protocole peut effectuer la procédure ci-dessus plusieurs fois à l’aide de la même clé principale. Cela permet au client et au serveur d’avoir plusieurs connexions simultanées, chacune utilisant des clés MAC et de chiffrement en bloc différentes sans opérations RSA ou Diffie-Hellman supplémentaires.
Tous les fournisseurs de services cloud doivent utiliser de bonnes pratiques de thread-safe. Les nombres de threads de plusieurs dizaines ne sont pas inhabituels.
Voici un code source classique pour le moteur de protocole :
//--------------------------------------------------------------------
// Define and initialize local variables.
BOOL fClient = <TRUE if this is code for the client?>;
CRYPT_DATA_BLOB Data;
HCRYPTHASH hMasterHash;
//--------------------------------------------------------------------
// Finish creating the master_secret.
switch(<protocol being used>)
{
case <PCT 1.0>:
//------------------------------------------------------------
// Specify clear key value.
Data.pbData = pClearKey;
Data.cbData = cbClearKey;
CryptSetKeyParam(
hMasterKey,
KP_CLEAR_KEY,
(PBYTE)&Data,
0);
//------------------------------------------------------------
// Specify the CH_CHALLENGE_DATA.
Data.pbData = pChallenge;
Data.cbData = cbChallenge;
CryptSetKeyParam(
hMasterKey,
KP_CLIENT_RANDOM,
(PBYTE)&Data,
0);
//------------------------------------------------------------
// Specify the SH_CONNECTION_ID_DATA.
Data.pbData = pConnectionID;
Data.cbData = cbConnectionID;
CryptSetKeyParam(
hMasterKey,
KP_SERVER_RANDOM,
(PBYTE)&Data,
0);
//------------------------------------------------------------
// Specify the SH_CERTIFICATE_DATA.
Data.pbData = pbServerCertificate;
Data.cbData = cbServerCertificate;
CryptSetKeyParam(
hMasterKey,
KP_CERTIFICATE,
(PBYTE)&Data,
0);
break;
case <SSL 2.0>:
//------------------------------------------------------------
// Specify clear key value.
Data.pbData = pClearKey;
Data.cbData = cbClearKey;
CryptSetKeyParam(
hMasterKey,
KP_CLEAR_KEY,
(PBYTE)&Data,
0);
//------------------------------------------------------------
// Specify the CH_CHALLENGE_DATA.
Data.pbData = pChallenge;
Data.cbData = cbChallenge;
CryptSetKeyParam(
hMasterKey,
KP_CLIENT_RANDOM,
(BYTE*)&Data,
0);
//------------------------------------------------------------
// Specify the SH_CONNECTION_ID_DATA.
Data.pbData = pConnectionID;
Data.cbData = cbConnectionID;
CryptSetKeyParam(
hMasterKey,
KP_SERVER_RANDOM,
(BYTE*)&Data,
0);
break;
case <SSL 3.0>:
case <TLS 1.0>:
//------------------------------------------------------------
// Specify client_random.
Data.pbData = pClientRandom;
Data.cbData = cbClientRandom;
CryptSetKeyParam(
hMasterKey,
KP_CLIENT_RANDOM,
(PBYTE)&Data,
0);
//------------------------------------------------------------
// Specify server_random.
Data.pbData = pServerRandom;
Data.cbData = cbServerRandom;
CryptSetKeyParam(
hMasterKey,
KP_SERVER_RANDOM,
(PBYTE)&Data,
0);
}
//------------------------------------------------------------
// Create the master hash object from the master key.
CryptCreateHash(
hProv,
CALG_SCHANNEL_MASTER_HASH,
hMasterKey,
0,
&hMasterHash);
//------------------------------------------------------------
// Derive read key from the master hash object.
CryptDeriveKey(hProv,
CALG_SCHANNEL_ENC_KEY,
hMasterHash,
fClient ? CRYPT_SERVER : 0,
&hReadKey);
//------------------------------------------------------------
// Derive write key from the master hash object.
CryptDeriveKey(
hProv,
CALG_SCHANNEL_ENC_KEY,
hMasterHash,
fClient ? 0 : CRYPT_SERVER,
&hWriteKey);
if(<protocol being used> != <SSL 2.0>) // for SSL 2.0, the master
// key is also the MAC.
{
//------------------------------------------------------------
// Derive read MAC from the master hash object.
CryptDeriveKey(
hProv,
CALG_SCHANNEL_MAC_KEY,
hMasterHash,
fClient ? CRYPT_SERVER : 0,
&hReadMAC);
//------------------------------------------------------------
// Derive write MAC from the master hash object.
CryptDeriveKey(
hProv,
CALG_SCHANNEL_MAC_KEY,
hMasterHash,
fClient ? 0 : CRYPT_SERVER,
&hWriteMAC);
}
CryptDestroyHash(hMasterHash);