📄 rsakey.cpp
字号:
k1.key.ep != k2.key.ep || k1.key.eq != k2.key.eq || k1.key.r != k2.key.r || k1.key.bitlen_mod != k2.key.bitlen_mod || k1.key.bytelen_mod != k2.key.bytelen_mod); // Operator != returns 1 if k1 != k2, 0 else}fstream& operator<< (fstream& s, const 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; 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// ConstructorRSApub::RSApub (const RSAkey& k){ pkey = k.export_public ();}// RSA-encryptionLINT RSApub::crypt (const UCHAR* Mess, int LenMess, STATEPRNG& xrstate){ int LenEncryptionBlock = pkey.bytelen_mod; UCHAR* EncryptionBlock = new UCHAR[LenEncryptionBlock]; // Format Encryption Block acc. to PKCS#1 if (NULL == format_pkcs1 (EncryptionBlock, LenEncryptionBlock, BLOCKTYPE_ENCR, Mess, (ULONG)LenMess, xrstate)) { 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-signatureint RSApub::verify (const UCHAR* Mess, int LenMess, const LINT& Signature){ int length, BlockType, verification = 0; UCHAR H1[RMDVER>>3]; UCHAR* H2 = NULL; UCHAR* EB = lint2byte (mexpkm (Signature, pkey.pubexp, pkey.mod), &length); sha1_l (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 BlockType = parse_pkcs1 (H2, &length, EB, pkey.bytelen_mod); if ((BlockType == 0 || BlockType == 1) && (H2 != NULL) && (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 keyvoid RSApub::purge (void){ pkey.pubexp.purge (); pkey.mod.purge (); pkey.bitlen_mod = 0; pkey.bytelen_mod = 0;}// Operators =, ==, != of class RSApubRSApub& 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 = 00||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) - 11, pointed to by// parameter data, length k in parameter LenData// Length of modulus in bytes is passed in LenMod// Parameter EB points to buffer for Encryption Block// buffer must be allocated by calling function, length of buffer at least// byte length of modulusUCHAR* format_pkcs1 (UCHAR* EB, int LenMod, UCHAR BlockType, const UCHAR* data, int LenData, STATEPRNG& xrstate){ // Calculate length lps of padding block int lps = LenMod - 3 - LenData; if (lps < 8) // PKCS#1: Length padding block >= 8 { return NULL; // NULL pointer indicates error status } UCHAR* hlp = EB; *hlp++ = 0x00; // Leading octet 0x00 switch (BlockType) { case BLOCKTYPE_SIGN: *hlp++ = 0x01; // Block Type 01: Private Key Operation while (lps-- > 0) { *hlp++ = 0xff; // 8 <= lps bytes 0xFF } break; case BLOCKTYPE_ENCR: *hlp++ = 0x02; // Block Type 02: Public Key Operation while (lps-- > 0) { do { *hlp = bRand_l (&xrstate); } // 8 <= lps random bytes not zero while (*hlp == 0); ++hlp; } break; default: return NULL; // Error: Undefined Block Type in BlockType } *hlp++ = 0x00; // Separating octet for (int l = 1; l <= LenData; l++) { *hlp++ = *data++; } return (UCHAR*)EB;}// Parser for decrypted Encryption Block, PKCS#1-formatted// Pointer to data is stored in PayLoad// Length of data (number of bytes) is stored in LenData// Returns determined Block Type// -1 is returned to indicate format error statusint parse_pkcs1 (UCHAR*& PayLoad, int* LenData, UCHAR* EB, int LenMod){ PayLoad = EB; UCHAR BlockType; int error = 0, noofpadc = 0; // Check implicitly for the leading 0x00-octet. The leading 0x00-octet as // leading zero is not reconstructed. However, would the octet be different // from 0x00, it would be reconstructed resulting in a length of the // reconstructed encryption block equal to the length of the modulus. This // error condition is checked here. // Check Block Type explicitly: 00, 01, 02 are valid if ((*LenData != LenMod - 1) || (BlockType = *EB) > 2) { return -1; } ++PayLoad; --*LenData; switch (BlockType) { case 0: case 1: // Block Type 00 or 01: Private Key Operation while (*PayLoad != 0 && *LenData > 0) // Analyze padding string PS { if (*PayLoad != 0xff) { error = 1; // Check padding == 0xFF for Block Type 01 break; // Set errorflag error to 1 if byte != 0xFF } ++PayLoad; --*LenData; ++noofpadc; }; break; case 2: // Block Type 02: Public Key Operation while (*PayLoad != 0 && *LenData > 0) // Search end of padding string PS { ++PayLoad; --*LenData; ++noofpadc; }; break; default: PayLoad = (UCHAR*)NULL; return -1; // Invalid Block Type } if (noofpadc < 8 || error || *LenData == 0) { PayLoad = (UCHAR*)NULL; // Summarize result of padding check return -1; // Error status indicated by -1 } else { ++PayLoad; // Skip separation byte 00 --*LenData; // Byte length of payload in LenData } return BlockType; //Return Block Type}#ifdef FLINT_TEST// Output of message as Hex-valuestatic void cout_mess (const char* mess, int len, const char* titel){ cout << titel << " = " << hex << setfill ('0') << resetiosflags (ios::showbase); if (mess > NULL) { 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 + -