My current working environnement is:
- Language: C
- Application type: Win32
- Library: CryptoAPI
I want to encrypt a XML file with RSA algorithm, so here where I got my public key: https://csfieldguide.org.nz/en/interactives/rsa-key-generator/
By choosing 1024 bits, base 16 component, I receive directly:
exp:
01 00 01
mod:
00 90 0D 50 4E AA 5B A3 1E 26 53 54 70 D0 E7 C9 FE 45 AF 1F F6 27 71 DF 03 F9 EF 0F DD 78 CA 1F EE 5E FC BD 02 07 02 B6 F0 DB 30 84 86 94 53 0B C2 0A 82 B2 41 B7 FC 08 AD 42 09 68 3F 80 13 51 6E 2B 00 18 90 ED 7D F5 66 7E F5 2D 27 C8 62 4B 6C 85 BC 02 C2 A4 B5 F9 82 C7 19 A7 24 E7 FD 56 EA 6C 1A 3C 48 5B 57 AC 25 EE E1 36 34 22 10 DD 79 15 AF 38 D5 DF 4F 24 D3 EB AD CA 04 BB F0 30 9F
then I follow Microsoft's instruction to build my public key struct:
https://learn.microsoft.com/en-us/windows/win32/api/bcrypt/ns-bcrypt-bcrypt_rsakey_blob
struct RSAPublicKey
{
BCRYPT_RSAKEY_BLOB blob;
unsigned char exp[3];
unsigned char mod[128];
};
struct RSAPublicKey key;
key.blob.Magic = BCRYPT_RSAPUBLIC_MAGIC;
key.blob.cbPublicExp = 3;
key.blob.cbModulus = 128;
byte exp[3] = {0x01, 0x00, 0x01};
byte exp[128] = {0x00, 0x90...};
for (int cnt = 0; cnt < 2; cnt++) {
key.exp[cnt] = exp[cnt];
}
for (int cnt = 0; cnt < 128; cnt++) {
key.mod[cnt] = mod[cnt];
}
According to the document, the key structure should be big-endian, but when I call
NTSTATUS status = BCryptImportKeyPair(hRSAAlg, NULL, BCRYPT_RSAPUBLIC_BLOB, &hKey, &key, 155, 0);
status code is not correct, it take me so long to find the proper solution, then I found this, another person who asked a question and show his example like:
unsigned char PrivateKey[PrivateKeySize] = {
0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0xB7, 0x50, 0x52, 0xDD, 0x58, 0xE4, 0x96, 0xAF, 0x91, 0xE5, 0xB2, 0x7B, 0x0A, 0xE6, 0xAA, 0x1F, 0x71, 0x8A, 0x66, 0xC3, 0xF0, 0x21, 0xD8, 0xE6, 0x2C, 0xD6, 0x25, 0x2E, 0x77, 0x3C, 0x61, 0x08, 0x1B, 0x69, 0xE7, 0x58, 0xDF, 0x3B, 0x07, 0xFE, 0xF1, 0xDB, 0xBF, 0xA6, 0x35, 0xDF, 0xC7, 0x49, 0x06, 0xC8, 0xDB, 0x74, 0x2A, 0xB9, 0xED, 0xB3, 0x04, 0x80, 0x75, 0x5F, 0x71, 0x2C, 0xD0, 0x14, 0x0E, 0x81, 0x18, 0x00, 0x5E, 0x34, 0x5A, 0xC2, 0x3A, 0x84, 0x63, 0xB1, 0x6B, 0x04, 0x21, 0x49, 0x7F, 0xE0, 0xF3, 0x52, 0x5E, 0x61, 0x43, 0xB1, 0x8F, 0x7C, 0xF2, 0x74, 0x29, 0x28, 0x69, 0x20, 0x36, 0xC0, 0x92, 0x17, 0x42, 0x99, 0x72, 0xE5, 0xE7, 0x82, 0xBE, 0x8E, 0x3B, 0x3F, 0xC9, 0x0A, 0xE1, 0xC4, 0x63, 0x68, 0x73, 0x1D, 0x67, 0x8D, 0xC0, 0xA3, 0xB4, 0xBA, 0xF0, 0xB7, 0xB0, 0x9B, 0xBB, 0x3F, 0xB8, 0x6E, 0xC0, 0x34, 0x1E, 0xA0, 0x01, 0x4B, 0x6D, 0x47, 0x73, 0x3F, 0xA5, 0x39, 0x05, 0x27, 0xD4, 0xD1, 0x38, 0x34, 0x32, 0x2C, 0x5B, 0x03, 0x5F, 0x16, 0x21, 0x64, 0x04, 0xD5, 0x19, 0xDB, 0xE7, 0x80, 0xDA, 0xBD, 0xC4, 0x1E, 0xAB, 0x61, 0xC8, 0x84, 0xDF, 0x54, 0x16, 0x77, 0x98, 0x9B, 0x90, 0x03, 0x83, 0xC4, 0x8D, 0x25, 0xB1, 0x32, 0x67, 0x77, 0x6A, 0x1C, 0x64, 0x2D, 0xFA, 0x9E, 0xB9, 0x26, 0xB5, 0xF8, 0x47, 0x4A, 0x9C, 0x35, 0x89, 0x5F, 0x12, 0x0E, 0xFF, 0x60, 0x87, 0x1E, 0x27, 0xC1, 0xC5, 0x7C, 0x77, 0x0A, 0xAE, 0x11, 0x37, 0xE3, 0x42, 0x9B, 0xAF, 0x9D, 0xBC, 0xC2, 0x52, 0xF8, 0x85, 0xBA, 0xED, 0x8E, 0xC3, 0x73, 0x04, 0x0A, 0x53, 0xD2, 0x1D, 0xEF, 0xA0, 0x6A, 0xCD, 0xBE, 0x93, 0x49, 0x34, 0x3A, 0xBD, 0xDF, 0x6A, 0x33, 0x25, 0x91, 0xFC, 0xE7
};
and by replacing my own structure with his, all fine...
but I got confused, obviously, his structure is on little-endian, for example:
define BCRYPT_RSAPUBLIC_MAGIC 0x31415352
in his array, presented as 0x52, 0x53, 0x41, 0x32...
so here we go, so many questions I want to ask:
why 128 bytes mod has 129 bytes when I try to generate key by using https://csfieldguide.org.nz/en/interactives/rsa-key-generator/ is there a checksum byte or something need to be ignored?
ULONG is 8 bytes noramlly, but why in the working case which I found from somebody else, it seems to only take 4 bbytes?
why my solution not works, is should not be big-endian?
thanks alllllllot!!!