⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 highlvl.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 4 页
字号:
	cryptDestroyContext( cryptContext );

	/* Decrypt the buffer */
	status = cryptCreateContext( &cryptContext, CRYPT_UNUSED, CRYPT_ALGO_DES );
	if( cryptStatusError( status ) )
		return( FALSE );
	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 that it went OK */
	for( i = 0; i < ( int ) length; i++ )
		{
		if( buffer[ i ] != '*' )
			{
			printf( "Decrypted data != original plaintext at position %d, "
					"line %d.\n", i, __LINE__ );
			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 */

static int deriveKey( const C_STR userKey, const int userKeyLength )
	{
	CRYPT_CONTEXT cryptContext, decryptContext;
	int status;

	/* 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) */
	status = cryptCreateContext( &cryptContext, CRYPT_UNUSED,
								 selectCipher( CRYPT_ALGO_IDEA ) );
	if( cryptStatusOK( status ) )
		status = cryptCreateContext( &decryptContext, CRYPT_UNUSED,
									 selectCipher( CRYPT_ALGO_IDEA ) );
	if( cryptStatusError( status ) )
		return( FALSE );
	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 that the two derived keys match */
	if( !compareSessionKeys( cryptContext, decryptContext ) )
		return( FALSE );

	/* Clean up */
	destroyContexts( CRYPT_UNUSED, cryptContext, decryptContext );

	return( TRUE );
	}

int testDeriveKey( void )
	{
	CRYPT_CONTEXT cryptContext;
	C_STR shortUserKey = TEXT( "12345678" );
	C_STR medUserKey = TEXT( "This is a long user key for key derivation testing" );
	C_STR longUserKey = TEXT( "This is a really long user key that exceeds the HMAC input limit for keys" );
	BYTE buffer[ 8 ];
	int 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 */
	status = cryptCreateContext( &cryptContext, CRYPT_UNUSED, 
								 CRYPT_ALGO_DES );
	if( cryptStatusError( status ) )
		return( FALSE );
	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 );
		}

	/* Test the derivation of keys from short, medium, and long passwords */
	status = deriveKey( shortUserKey, paramStrlen( shortUserKey ) );
	if( status ) 
		status = deriveKey( medUserKey, paramStrlen( medUserKey ) );
	if( status ) 
		status = deriveKey( longUserKey, paramStrlen( longUserKey ) );
	if( !status ) 
		return( FALSE );

	/* Test the derivation process using fixed test data: password =
	   "password", salt = { 0x12 0x34 0x56 0x78 0x78 0x56 0x34 0x12 },
	   iterations = 5 */
	status = cryptCreateContext( &cryptContext, CRYPT_UNUSED, 
								 CRYPT_ALGO_DES );
	if( cryptStatusError( status ) )
		return( FALSE );
	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:

	const C_STR userKey = "password"; 
	const int 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 ); 

	To create the PKCS #5 v2.0 Amd.1 test vectors use:

	const C_STR userKey = "foo123"; 
	const int userKeyLength = 6;

	cryptCreateContext( &cryptContext, CRYPT_UNUSED, CRYPT_ALGO_3DES );
	cryptSetAttribute( cryptContext, CRYPT_CTXINFO_KEYING_ITERATIONS, 1000 );
	cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_KEYING_SALT,
							 "\x12\x3E\xFF\x3C\x4A\x72\x12\x9C", 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 */
	status = cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_KEYING_SALT,
									  "\x12\x34\x56\x78\x78\x56\x34\x12", 8 );
	if( cryptStatusOK( status ) )
		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 that 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 */
	status = cryptCreateContext( &sessionKeyContext1, CRYPT_UNUSED, 
								 CRYPT_ALGO_3DES );
	if( cryptStatusOK( status ) )
		status = cryptSetAttribute( sessionKeyContext1, CRYPT_CTXINFO_MODE, 
									CRYPT_MODE_CFB );
	if( cryptStatusOK( status ) )
		status = cryptGenerateKey( sessionKeyContext1 );
	if( cryptStatusOK( status ) )
		status = cryptCreateContext( &sessionKeyContext2, CRYPT_UNUSED, 
									 CRYPT_ALGO_3DES );
	if( cryptStatusOK( status ) )
		status = cryptSetAttribute( sessionKeyContext2, CRYPT_CTXINFO_MODE, 
									CRYPT_MODE_CFB );
	if( cryptStatusError( status ) )
		{
		printf( "Session key context setup failed with error code %d, line "
				"%d.\n", status, __LINE__ );
		return( FALSE );
		}

	/* Create a Blowfish context to export the session key */
	status = cryptCreateContext( &cryptContext, CRYPT_UNUSED,
								 selectCipher( 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 */
	status = cryptCreateContext( &sessionKeyContext1, CRYPT_UNUSED, 
								 selectCipher( CRYPT_ALGO_AES ) );
	if( cryptStatusOK( status ) )
		status = cryptSetAttribute( sessionKeyContext1, CRYPT_CTXINFO_MODE, 
									CRYPT_MODE_CFB );
	if( cryptStatusOK( status ) )
		status = cryptGenerateKey( sessionKeyContext1 );
	if( cryptStatusOK( status ) )
		{
		status = cryptCreateContext( &sessionKeyContext2, CRYPT_UNUSED, 
									 selectCipher( CRYPT_ALGO_AES ) );
		cryptSetAttribute( sessionKeyContext2, CRYPT_CTXINFO_MODE, 
							CRYPT_MODE_CFB );
		}
	if( cryptStatusError( status ) )
		{
		printf( "Session key context setup failed with error code %d, line "
				"%d.\n", status, __LINE__ );
		return( FALSE );
		}
	status = cryptCreateContext( &cryptContext, CRYPT_UNUSED, 
								 selectCipher( 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,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -