C++、C#、秘密鍵、公開鍵、RSA
RSAの鍵作成(C++)->暗号化(C#)->復号化(C++)の例
暗号化(C#)int _tmain(int argc, _TCHAR* argv[])
{
// RSA 秘密鍵と公開鍵を作成し、両方をファイル化HCRYPTPROV hCryptprov;
BOOL bl = CryptAcquireContext(&hCryptprov, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, 0 );
ATLASSERT( bl );HCRYPTKEY hKey;
bl = CryptGenKey(hCryptprov, CALG_RSA_KEYX, KEYLENGTH<<16 | CRYPT_EXPORTABLE, &hKey);
ATLASSERT( bl );DWORD dwPrivateKeySize;
bl = CryptExportKey( hKey, 0, PRIVATEKEYBLOB,0, NULL, &dwPrivateKeySize); // サイズ取得
BYTE* privateKey = new BYTE[dwPrivateKeySize];
bl = CryptExportKey( hKey, 0, PRIVATEKEYBLOB,0, privateKey, &dwPrivateKeySize); // 596
ATLASSERT( bl );DWORD dwPublicKeySize;
bl = CryptExportKey( hKey, 0, PUBLICKEYBLOB,0, NULL, &dwPublicKeySize); // サイズ取得
BYTE* publicKey = new BYTE[dwPublicKeySize];
bl = CryptExportKey( hKey, 0, PUBLICKEYBLOB,0, publicKey, &dwPublicKeySize); // 148
ATLASSERT( bl );FILE* pf = fopen( "privatekey.bin", "wb" );
fwrite( privateKey, 1, dwPrivateKeySize, pf );
fclose(pf);pf = fopen( "publickey.bin", "wb" );
fwrite( publicKey, 1, dwPublicKeySize, pf );
fclose(pf);
delete [] privateKey;
delete [] publicKey;CryptDestroyKey( hKey );
CryptReleaseContext(hCryptprov, 0);return 0;
}
復号化(C++)
{
// RSA 1024bit
var rsa = new System.Security.Cryptography.RSACryptoServiceProvider();// 公開鍵を受け取る
BinaryReader sr = new BinaryReader( File.OpenRead("publickey.bin"));
long len = sr.BaseStream.Length;
Byte [] blob = new Byte[len];
sr.Read( blob, 0, (int)len );
sr.Close();
// 公開鍵をインポート
rsa.ImportCspBlob( blob );// 公開鍵で暗号化
byte[] data = rsa.Encrypt( Encoding.ASCII.GetBytes("password"), false ); // パスワードは英数字が普通なので、ASCIIエンコード// ファイル化
BinaryWriter wr = new BinaryWriter( File.OpenWrite("encrypt.bin"));
wr.Write( data, 0, data.Length );
wr.Close();
}
BYTE* MyFileRead( LPCSTR fnm, DWORD* plen );
BYTE* ByteArraySwap( BYTE* buffer, int len );int _tmain(int argc, _TCHAR* argv[])
{
HCRYPTPROV hCryptprov;
HCRYPTKEY hkey;
BOOL bl = CryptAcquireContext(&hCryptprov, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, 0 );
ATLASSERT( bl );DWORD prlen,dlen;
// 秘密鍵
BYTE* privatekey = MyFileRead( "privatekey.bin" , &prlen);
// 暗号化されたデータ
BYTE* data = MyFileRead( "encrypt.bin", &dlen );
// 復号化のため、秘密鍵をインポート
bl = CryptImportKey( hCryptprov, privatekey, prlen, 0 ,0, &hkey );
ATLASSERT( bl );BYTE* ctext = ByteArraySwap( data, dlen ); // to big endian
// 復号化
bl = ::CryptDecrypt( hkey, 0, TRUE,0, ctext, &dlen );
ATLASSERT( bl );
CStringA str((LPCSTR)ctext, dlen); // 元がEncoding.ASCII.GetBytesなのでそのままLPCSTRになるATLASSERT( str == "password" );
delete [] privatekey;
delete [] ctext;CryptDestroyKey( hkey );
CryptReleaseContext(hCryptprov, 0);return 0;
}BYTE* MyFileRead( LPCSTR fnm, DWORD* plen )
{
FILE* pf = ::fopen( fnm, "rb" );
::fseek( pf, 0, SEEK_END );
DWORD len = ::ftell(pf);
::fseek( pf, 0, SEEK_SET );BYTE* buf = new BYTE[len];
::fread( buf,1,len,pf);
fclose(pf);*plen = len;
return buf;
}
static BYTE* ByteArraySwap( BYTE* buffer, int len )
{
BYTE* buffer2 = new BYTE[ len ];
for(int i = 0; i < len; i++)
buffer2[i] = buffer[len-i-1];delete [] buffer;
return buffer2;
}