📄 highlvl.c
字号:
memset( buffer, '*', length );
/* Encrypt the buffer */
cryptCreateContext( &cryptContext, CRYPT_UNUSED, CRYPT_ALGO_DES );
cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_KEY, "12345678", 8 );
cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_IV,
"\x00\x00\x00\x00\x00\x00\x00\x00", 8 );
status = cryptEncrypt( cryptContext, buffer, length );
if( cryptStatusError( status ) )
{
printf( "cryptEncrypt() of large data quantity failed with error "
"code %d, line %d.\n", status, __LINE__ );
return( FALSE );
}
cryptDestroyContext( cryptContext );
/* Decrypt the buffer */
cryptCreateContext( &cryptContext, CRYPT_UNUSED, CRYPT_ALGO_DES );
cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_KEY, "12345678", 8 );
cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_IV,
"\x00\x00\x00\x00\x00\x00\x00\x00", 8 );
status = cryptDecrypt( cryptContext, buffer, length );
if( cryptStatusError( status ) )
{
printf( "cryptDecrypt() of large data quantity failed with error "
"code %d, line %d.\n", status, __LINE__ );
return( FALSE );
}
cryptDestroyContext( cryptContext );
/* Make sure it went OK */
for( i = 0; i < ( int ) length; i++ )
if( buffer[ i ] != '*' )
{
printf( "Decrypted data != original plaintext at position %d.\n",
i );
return( FALSE );
}
/* Clean up */
free( buffer );
printf( "Encryption of %ld bytes of data succeeded.\n\n",
( long ) length );
return( TRUE );
}
/* Test the code to derive a fixed-length encryption key from a variable-
length user key */
int testDeriveKey( void )
{
CRYPT_CONTEXT cryptContext, decryptContext;
C_STR userKey = TEXT( "This is a long user key for key derivation testing" );
BYTE buffer[ 8 ];
int userKeyLength = paramStrlen( userKey ), value, status;
puts( "Testing key derivation..." );
/* Make sure that we can get/set the keying values with equivalent
systemwide settings using either the context-specific or global
option attributes */
cryptCreateContext( &cryptContext, CRYPT_UNUSED, CRYPT_ALGO_DES );
status = cryptSetAttribute( cryptContext,
CRYPT_CTXINFO_KEYING_ITERATIONS, 5 );
if( cryptStatusOK( status ) )
status = cryptGetAttribute( cryptContext,
CRYPT_OPTION_KEYING_ITERATIONS,
&value );
cryptDestroyContext( cryptContext );
if( cryptStatusError( status ) || value != 5 )
{
printf( "Failed to get/set context attribute via equivalent global "
"attribute, error\ncode %d, value %d (should be 5), line "
"%d.\n", status, value, __LINE__ );
return( FALSE );
}
/* Create IDEA/CBC encryption and decryption contexts and load them with
identical salt values for the key derivation (this is easier than
reading the salt from one and writing it to the other) */
cryptCreateContext( &cryptContext, CRYPT_UNUSED,
selectCipher( CRYPT_ALGO_IDEA ) );
cryptCreateContext( &decryptContext, CRYPT_UNUSED,
selectCipher( CRYPT_ALGO_IDEA ) );
cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_KEYING_SALT,
"\x12\x34\x56\x78\x78\x56\x34\x12", 8 );
cryptSetAttributeString( decryptContext, CRYPT_CTXINFO_KEYING_SALT,
"\x12\x34\x56\x78\x78\x56\x34\x12", 8 );
/* Load an IDEA key derived from a user key into both contexts */
status = cryptSetAttributeString( cryptContext,
CRYPT_CTXINFO_KEYING_VALUE,
userKey, userKeyLength );
if( cryptStatusError( status ) )
{
printf( "Key derivation failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
status = cryptSetAttributeString( decryptContext,
CRYPT_CTXINFO_KEYING_VALUE,
userKey, userKeyLength );
if( cryptStatusError( status ) )
{
printf( "Key derivation failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
/* Make sure the two derived keys match */
if( !compareSessionKeys( cryptContext, decryptContext ) )
return( FALSE );
/* Clean up */
destroyContexts( CRYPT_UNUSED, cryptContext, decryptContext );
/* Test the derivation process using fixed test data: password =
"password", salt = { 0x12 0x34 0x56 0x78 0x78 0x56 0x34 0x12 },
iterations = 5 */
cryptCreateContext( &cryptContext, CRYPT_UNUSED, CRYPT_ALGO_DES );
cryptSetAttribute( cryptContext, CRYPT_CTXINFO_MODE, CRYPT_MODE_ECB );
cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_KEYING_SALT,
"\x12\x34\x56\x78\x78\x56\x34\x12", 8 );
cryptSetAttribute( cryptContext, CRYPT_CTXINFO_KEYING_ITERATIONS, 5 );
cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_KEYING_VALUE,
TEXT( "password" ),
paramStrlen( TEXT( "password" ) ) );
memset( buffer, 0, 8 );
cryptEncrypt( cryptContext, buffer, 8 );
cryptDestroyContext( cryptContext );
if( memcmp( buffer, "\x9B\xBD\x78\xFC\x11\xA3\xA9\x08", 8 ) )
{
puts( "Derived key value doesn't match predefined test value." );
return( FALSE );
}
puts( "Key exchange via derived key succeeded.\n" );
return( TRUE );
}
/* Test the code to export/import an encrypted key via conventional
encryption.
To create the CMS PWRI test vectors, substitute the following code for the
normal key load:
userKey = "password"; userKeyLength = 8;
cryptCreateContext( &sessionKeyContext1, CRYPT_UNUSED, CRYPT_ALGO_DES );
cryptSetAttributeString( sessionKeyContext1, CRYPT_CTXINFO_KEY,
"\x8C\x63\x7D\x88\x72\x23\xA2\xF9", 8 );
cryptCreateContext( &cryptContext, CRYPT_UNUSED, CRYPT_ALGO_DES );
cryptSetAttribute( cryptContext, CRYPT_CTXINFO_KEYING_ITERATIONS, 5 );
cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_KEYING_SALT,
"\x12\x34\x56\x78\x78\x56\x34\x12", 8 );
status = cryptSetAttributeString( cryptContext,
CRYPT_CTXINFO_KEYING_VALUE,
userKey, userKeyLength ); */
static int conventionalExportImport( const CRYPT_CONTEXT cryptContext,
const CRYPT_CONTEXT sessionKeyContext1,
const CRYPT_CONTEXT sessionKeyContext2 )
{
CRYPT_OBJECT_INFO cryptObjectInfo;
CRYPT_CONTEXT decryptContext;
BYTE *buffer;
const C_STR userKey = TEXT( "All n-entities must communicate with other n-entities via n-1 entiteeheehees" );
const int userKeyLength = paramStrlen( userKey );
int length, status;
/* Set the key for the exporting context */
cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_KEYING_SALT,
"\x12\x34\x56\x78\x78\x56\x34\x12", 8 );
status = cryptSetAttributeString( cryptContext,
CRYPT_CTXINFO_KEYING_VALUE,
userKey, userKeyLength );
if( cryptStatusError( status ) )
{
printf( "cryptSetAttributeString() failed with error code %d, line "
"%d.\n", status, __LINE__ );
return( FALSE );
}
/* Find out how big the exported key will be */
status = cryptExportKey( NULL, 0, &length, cryptContext,
sessionKeyContext1 );
if( cryptStatusError( status ) )
{
printf( "cryptExportKey() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
printf( "cryptExportKey() reports exported key object will be %d bytes "
"long\n", length );
if( ( buffer = malloc( length ) ) == NULL )
return( FALSE );
/* Export the session information */
status = cryptExportKey( buffer, length, &length, cryptContext,
sessionKeyContext1 );
if( cryptStatusError( status ) )
{
printf( "cryptExportKey() failed with error code %d, line %d.\n",
status, __LINE__ );
free( buffer );
return( FALSE );
}
/* Query the encrypted key object */
status = cryptQueryObject( buffer, length, &cryptObjectInfo );
if( cryptStatusError( status ) )
{
printf( "cryptQueryObject() failed with error code %d, line %d.\n",
status, __LINE__ );
free( buffer );
return( FALSE );
}
printf( "cryptQueryObject() reports object type %d, algorithm %d, mode "
"%d.\n", cryptObjectInfo.objectType, cryptObjectInfo.cryptAlgo,
cryptObjectInfo.cryptMode );
debugDump( ( cryptObjectInfo.cryptAlgo == CRYPT_ALGO_AES ) ? \
"kek_aes" : "kek", buffer, length );
/* Recreate the session key by importing the encrypted key */
status = cryptCreateContext( &decryptContext, CRYPT_UNUSED,
cryptObjectInfo.cryptAlgo );
if( cryptStatusError( status ) )
{
printf( "cryptCreateContext() failed with error code %d, line %d.\n",
status, __LINE__ );
free( buffer );
return( FALSE );
}
cryptSetAttribute( decryptContext, CRYPT_CTXINFO_MODE,
cryptObjectInfo.cryptMode );
status = cryptSetAttributeString( decryptContext,
CRYPT_CTXINFO_KEYING_SALT,
cryptObjectInfo.salt,
cryptObjectInfo.saltSize );
if( cryptStatusOK( status ) )
status = cryptSetAttributeString( decryptContext,
CRYPT_CTXINFO_KEYING_VALUE,
userKey, userKeyLength );
if( cryptStatusError( status ) )
{
printf( "cryptSetAttributeString() failed with error code %d, line "
"%d.\n", status, __LINE__ );
return( FALSE );
}
status = cryptImportKey( buffer, length, decryptContext,
sessionKeyContext2 );
if( cryptStatusError( status ) )
{
printf( "cryptImportKey() failed with error code %d, line %d.\n",
status, __LINE__ );
free( buffer );
return( FALSE );
}
/* Make sure the two keys match */
if( !compareSessionKeys( sessionKeyContext1, sessionKeyContext2 ) )
return( FALSE );
/* Clean up */
cryptDestroyContext( decryptContext );
free( buffer );
return( TRUE );
}
int testConventionalExportImport( void )
{
CRYPT_CONTEXT cryptContext;
CRYPT_CONTEXT sessionKeyContext1, sessionKeyContext2;
int status;
puts( "Testing conventional key export/import..." );
/* Create triple-DES contexts for the session key and a Blowfish context
to export the session key */
cryptCreateContext( &sessionKeyContext1, CRYPT_UNUSED, CRYPT_ALGO_3DES );
cryptSetAttribute( sessionKeyContext1, CRYPT_CTXINFO_MODE, CRYPT_MODE_CFB );
cryptGenerateKey( sessionKeyContext1 );
cryptCreateContext( &sessionKeyContext2, CRYPT_UNUSED, CRYPT_ALGO_3DES );
cryptSetAttribute( sessionKeyContext2, CRYPT_CTXINFO_MODE, CRYPT_MODE_CFB );
status = cryptCreateContext( &cryptContext, CRYPT_UNUSED, CRYPT_ALGO_BLOWFISH );
if( cryptStatusError( status ) )
{
printf( "Export key context setup failed with error code %d, line "
"%d.\n", status, __LINE__ );
return( FALSE );
}
/* Export the key */
if( !conventionalExportImport( cryptContext, sessionKeyContext1,
sessionKeyContext2 ) )
return( FALSE );
cryptDestroyContext( cryptContext );
destroyContexts( CRYPT_UNUSED, sessionKeyContext1, sessionKeyContext2 );
puts( "Export/import of Blowfish key via user-key-based triple DES "
"conventional\n encryption succeeded." );
/* Create AES contexts for the session key and another AES context to
export the session key */
cryptCreateContext( &sessionKeyContext1, CRYPT_UNUSED, CRYPT_ALGO_AES );
cryptSetAttribute( sessionKeyContext1, CRYPT_CTXINFO_MODE, CRYPT_MODE_CFB );
cryptGenerateKey( sessionKeyContext1 );
cryptCreateContext( &sessionKeyContext2, CRYPT_UNUSED, CRYPT_ALGO_AES );
cryptSetAttribute( sessionKeyContext2, CRYPT_CTXINFO_MODE, CRYPT_MODE_CFB );
status = cryptCreateContext( &cryptContext, CRYPT_UNUSED, CRYPT_ALGO_AES );
if( cryptStatusError( status ) )
{
printf( "Export key context setup failed with error code %d, line "
"%d.\n", status, __LINE__ );
return( FALSE );
}
/* Export the key */
if( !conventionalExportImport( cryptContext, sessionKeyContext1,
sessionKeyContext2 ) )
return( FALSE );
cryptDestroyContext( cryptContext );
destroyContexts( CRYPT_UNUSED, sessionKeyContext1, sessionKeyContext2 );
puts( "Export/import of AES key via user-key-based AES conventional "
"encryption\n succeeded.\n" );
return( TRUE );
}
int testMACExportImport( void )
{
CRYPT_OBJECT_INFO cryptObjectInfo;
CRYPT_CONTEXT cryptContext, decryptContext;
CRYPT_CONTEXT macContext1, macContext2;
BYTE mac1[ CRYPT_MAX_HASHSIZE ], mac2[ CRYPT_MAX_HASHSIZE ];
C_STR userKey = TEXT( "This is a long user key for MAC testing" );
BYTE *buffer;
int userKeyLength = paramStrlen( userKey );
int status, length1, length2;
puts( "Testing MAC key export/import..." );
/* Create HMAC-SHA1 contexts for the MAC key */
cryptCreateContext( &macContext1, CRYPT_UNUSED, CRYPT_ALGO_HMAC_SHA );
cryptGenerateKey( macContext1 );
cryptCreateContext( &macContext2, CRYPT_UNUSED, CRYPT_ALGO_HMAC_SHA );
/* Create a 3DES encryption context to export the MAC key */
cryptCreateContext( &cryptContext, CRYPT_UNUSED, CRYPT_ALGO_3DES );
cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_KEYING_SALT,
"\x12\x34\x56\x78\x78\x56\x34\x12", 8 );
status = cryptSetAttributeString( cryptContext,
CRYPT_CTXINFO_KEYING_VALUE,
userKey, userKeyLength );
/* Find out how big the exported key will be */
status = cryptExportKey( NULL, 0, &length1, cryptContext, macContext1 );
if( cryptStatusError( status ) )
{
printf( "cryptExportKey() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
printf( "cryptExportKey() reports exported key object will be %d bytes "
"long\n", length1 );
if( ( buffer = malloc( length1 ) ) == NULL )
return( FALSE );
/* Export the MAC information */
status = cryptExportKey( buffer, length1, &length1, cryptContext,
macContext1 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -