📄 rsakey.cpp
字号:
{
s << k.key.pubexp << k.key.prvexp << k.key.mod << k.key.p << k.key.q
<< k.key.ep << k.key.eq << k.key.r;
write_ind_ushort (s, k.key.bitlen_mod);
write_ind_ushort (s, k.key.bytelen_mod);
return s;
}
fstream& operator>> (fstream& s, RSAkey& k)
{
s >> k.key.pubexp >> k.key.prvexp >> k.key.mod >> k.key.p >> k.key.q
>> k.key.ep >> k.key.eq >> k.key.r;
read_ind_ushort (s, &k.key.bitlen_mod);
read_ind_ushort (s, &k.key.bytelen_mod);
return s;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Member functions of class RSApub
// Constructor
RSApub::RSApub (const RSAkey& k)
{
pkey = k.export_public ();
}
RSApub::RSApub (const PKEYSTRUCT& p)
{
pkey.bitlen_mod = p.bitlen_mod;
pkey.bytelen_mod = p.bytelen_mod;
pkey.mod = p.mod;
pkey.pubexp =p.pubexp ;
}
// RSA-encryption
LINT RSApub::crypt (const UCHAR* const Mess, const int LenMess)
{
int LenEncryptionBlock = pkey.bytelen_mod - 1;
UCHAR* EncryptionBlock = new UCHAR[LenEncryptionBlock];
// Format Encryption Block acc. to PKCS#1
if (NULL == format_pkcs1 (EncryptionBlock,
LenEncryptionBlock,
BLOCKTYPE_ENCR,
Mess,
(ULONG)LenMess))
{
delete [] EncryptionBlock;
return LINT (0); // Error: Message too long
}
#ifdef FLINT_TEST
cout_mess ((const char*)EncryptionBlock, LenEncryptionBlock, "Encryption Block before encryption");
#endif
// Convert Encryption Block into LINT-value (Constructor 3)
LINT m = LINT (EncryptionBlock, LenEncryptionBlock);
delete [] EncryptionBlock;
return (mexpkm (m, pkey.pubexp, pkey.mod));
}
// Verify RSA-signature
UCHAR* RSApub::verify (int* length, const LINT& Signature)
{
// verification = 0;
// UCHAR H1[RMDVER>>3];
UCHAR* H2 = lint2byte (mexpkm (Signature, pkey.pubexp, pkey.mod), length);
// ripemd160 (H1, (UCHAR*)Mess, (ULONG)LenMess);
#ifdef FLINT_TEST
cout_mess ((const char*)H2, pkey.bytelen_mod - 1, "Encryption Block when signature is being verified");
#endif
// Read data from decrypted Encryption Block, PKCS#1-formatted
// H2 = parse_pkcs1 (H2, &length);
return parse_pkcs1 (H2, length);
/* if (length == (RMDVER >> 3))
{
verification = !memcmp ((char*)H1, (char*)H2, RMDVER >> 3);
}
#ifdef FLINT_TEST
cout_mess ((const char*)H2, length, "Hash-Wert when signature is being verified");
cout << "Verification = " << verification << endl;
#endif
return verification;*/
}
// Delete public key
void RSApub::purge (void)
{
pkey.pubexp.purge ();
pkey.mod.purge ();
pkey.bitlen_mod = 0;
pkey.bytelen_mod = 0;
}
// Operators =, ==, != of class RSApub
RSApub& RSApub::operator= (const RSApub &k)
{
if ((&k != this)) // Don't copy object into itself
{
pkey.pubexp = k.pkey.pubexp;
pkey.mod = k.pkey.mod;
pkey.bitlen_mod = k.pkey.bitlen_mod;
pkey.bytelen_mod = k.pkey.bytelen_mod;
}
return *this;
}
int operator== (const RSApub& k1, const RSApub& k2)
{
if (&k1 == &k2) //lint !e506
{
return 1;
}
return (k1.pkey.pubexp == k2.pkey.pubexp &&
k1.pkey.mod == k2.pkey.mod &&
k1.pkey.bitlen_mod == k2.pkey.bitlen_mod &&
k1.pkey.bytelen_mod == k2.pkey.bytelen_mod);
// Operator == returns 1 if k1 == k2, 0 else
}
int operator!= (const RSApub& k1, const RSApub& k2)
{
if (&k1 == &k2) //lint !e506
{
return 0;
}
return (k1.pkey.pubexp != k2.pkey.pubexp ||
k1.pkey.mod != k2.pkey.mod ||
k1.pkey.bitlen_mod != k2.pkey.bitlen_mod ||
k1.pkey.bytelen_mod != k2.pkey.bytelen_mod);
// Operator != returns 1 if k1 != k2, 0 else
}
fstream& operator<< (fstream& s, const RSApub& k)
{
s << k.pkey.pubexp << k.pkey.mod;
write_ind_ushort (s, k.pkey.bitlen_mod);
write_ind_ushort (s, k.pkey.bytelen_mod);
return s;
}
fstream& operator>> (fstream& s, RSApub& k)
{
s >> k.pkey.pubexp >> k.pkey.mod;
read_ind_ushort (s, &k.pkey.bitlen_mod);
read_ind_ushort (s, &k.pkey.bytelen_mod);
//s >> k.pkey.bitlen_mod >> k.pkey.bytelen_mod;
return s;
}
// Format Encryption Blocks (EB) acc. to PKCS#1
// EB = BT||PS1...PSl||00||DATA1...DATAk
// BT = Block Type public key operation:
// 01 private key operation (signing)
// 02 public key operation (encryption)
// PSi = BT 01: Value FF (hex), 8 Byte at least
// BT 02: Random values, not zero, 8 bytes at least
// DATAi = Data bytes, k <= (byte length of modulus) - 10, pointed to by
// parameter data, length k in parameter LenData
// Parameter EB points to buffer for Encryption Block
// buffer must be allocated by calling function, length of buffer at least
// byte length of modulus
UCHAR* format_pkcs1 (const UCHAR* EB, const int LenEB, const UCHAR BlockType, const UCHAR* data, const int LenData)
{
// Calculate length lps of padding block
int lps = LenEB - 2 - LenData;
if (lps < 8) // PKCS#1: Length padding block >= 8
{
return NULL; // NULL pointer indicates error status
}
UCHAR* hlp = (UCHAR*)EB;
switch (BlockType)
{
case 01:
*hlp++ = 0x01; // Block Type 01: Private Key Operation
while (lps-- > 0)
{
*hlp++ = 0xff; // 8 <= lps Werte FF (hex)
}
break;
case 02: *hlp++ = 0x02; // Block Typ 02: Public Key Operation
while (lps-- > 0)
{
do
{
*hlp = ucrandBBS_l ();
} // 8 <= lps random bytes not zero
while (*hlp == 0);
++hlp;
}
break;
default:
return NULL; // Error: Undefined Block Type in BlockType
}
*hlp++ = 0x00; // Separation byte
for (int l = 1; l <= LenData; l++)
{
*hlp++ = *data++;
}
return (UCHAR*)EB;
}
// Parser for decrypted Encryption Block, PKCS#1-formatted
// Returns pointer to data as payload contained in EB,
// Length of data (number of bytes) is stored in LenData
// NULL is returned to indicate format error status
UCHAR* parse_pkcs1 (const UCHAR* eb, int* LenData)
{
UCHAR* hlp = (UCHAR*)eb;
UCHAR BlockType;
int error = 0, noofpadc = 0;
if ((BlockType = *hlp) > 2) // Check Block Type: 00, 01, 02 are valid
{
return (UCHAR*)NULL;
}
++hlp;
--*LenData;
switch (BlockType)
{
case 0:
case 1: // Block Type 00 oder 01: Private Key Operation
while (*hlp != 0 && *LenData > 0) // Analyse padding string PS
{
if (*hlp != 0xff)
{
error = 1; // Check padding == 0xFF for Block Type 01
break; // Set errorflag error to 1 if byte != 0xFF
}
++hlp;
--*LenData;
++noofpadc;
};
break;
case 2: // Block Type 02: Public Key Operation
while (*hlp != 0 && *LenData > 0) // Search end of padding string PS
{
++hlp;
--*LenData;
++noofpadc;
};
break;
default:
return (UCHAR*)NULL; // Invalid Block Typ
}
if (noofpadc < 8 || error || *LenData == 0)
{ // Summarize result of padding check
return (UCHAR*)NULL; // Error status indicated by NULL
}
else
{
++hlp; // Skip separation byte 00
--*LenData; // Byte length of payload in LenData
}
return hlp; //Return Pointer to payload
}
#ifdef FLINT_TEST
// Output of message as Hex-value
static void cout_mess (const char* mess, const int len, const char* const titel)
{
cout << titel << " = " << hex
<< setfill ('0') << resetiosflags (ios::showbase);
for (int i = 0; i < len; i++)
{
cout << setw (2) << (((unsigned)*mess++) & 0xff);
}
cout << setfill (' ') << resetiosflags (ios::hex) << endl;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -