115 lines
3.0 KiB
SourcePawn
115 lines
3.0 KiB
SourcePawn
/***
|
|
rsa.inc - RSA Encrypting Algorithms Library Functions
|
|
|
|
Version: 0.1
|
|
Date: 28-03-2015
|
|
Author: Statik
|
|
|
|
Provides RSA PKCS #1 v1.5 encrypting functions.
|
|
|
|
**UNFINISHED**
|
|
|
|
***/
|
|
|
|
#if defined _RSA_included
|
|
#endinput
|
|
#endif
|
|
|
|
#define _RSA_included
|
|
|
|
rsaEncrypt(const String:hexModulus[], const String:hexExponent[], const String:message[], String:ciphertext[], ctSize)
|
|
{
|
|
decl modulus[1024];
|
|
decl exponent[16];
|
|
|
|
if (!hexString2BigInt(hexModulus, modulus, sizeof(modulus)))
|
|
{
|
|
PrintDebug(GetCaller(), "Error encrypting passphrase: Invalid modulus.");
|
|
return;
|
|
}
|
|
|
|
if (!hexString2BigInt(hexExponent, exponent, sizeof(exponent)))
|
|
{
|
|
PrintDebug(GetCaller(), "Error encrypting passphrase: Invalid exponent.");
|
|
return;
|
|
}
|
|
|
|
new k = strlen(hexModulus);
|
|
new mSize = k + 1;
|
|
if (ctSize < mSize)
|
|
{
|
|
PrintDebug(GetCaller(), "Error encrypting passphrase: ciphertext size is can't be smaller than modulus size");
|
|
|
|
}
|
|
decl String:paddedMessage[mSize];
|
|
pkcs1v15Pad(message, k, paddedMessage, mSize);
|
|
PrintDebug(GetCaller(), "Padded message with PKCS#1 v1.5 standard (%i): \n%s", strlen(paddedMessage), paddedMessage);
|
|
|
|
decl numericMessage[mSize];
|
|
hexString2BigInt(paddedMessage, numericMessage, mSize);
|
|
|
|
decl encryptedMessage[mSize];
|
|
modpowBigInt(numericMessage, exponent, modulus, 16, encryptedMessage, mSize);
|
|
bigInt2HexString(encryptedMessage, ciphertext, ctSize);
|
|
}
|
|
|
|
pkcs1v15Pad(const String:data[], k, String:message[], maxSize) // Message must be even
|
|
{
|
|
new dSize = strlen(data);
|
|
new psSize = k - (dSize*2) - 6; // Padding string Size
|
|
decl String:ps[psSize+1]; // Padding string / 1 more to add the string delimiter
|
|
decl String:ds[(dSize*2)+1]; // Data string
|
|
new i;
|
|
for (i = 0; i < psSize; i++)
|
|
{
|
|
if ((i % 2) == 0) ps[i] = int2HexChar(GetRandomInt(1,15));
|
|
else ps[i] = int2HexChar(GetRandomInt(0,15));
|
|
}
|
|
ps[i] = 0;
|
|
for (i = 0; i < dSize; i++)
|
|
{
|
|
ds[i*2] = int2HexChar(data[i] / 16); // High nibble
|
|
ds[i*2+1] = int2HexChar(data[i] % 16); // Low nibble
|
|
}
|
|
ds[i*2] = 0;
|
|
|
|
Format(message, maxSize, "0002%s00%s", ps, ds);
|
|
}
|
|
|
|
encodeBase64(input[], paddingSize, String:output[], oSize)
|
|
{
|
|
static const String:base64Table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
|
|
new iSize = getBigIntSize(input);
|
|
if (paddingSize < iSize) return 0;
|
|
new zeros = paddingSize - iSize;
|
|
for (new e = 0; e < zeros; e++) { input[iSize++] = 0; }
|
|
new finalSize = (iSize / 6) * 4;
|
|
if (oSize < finalSize) return 0;
|
|
|
|
new bitString = 0, u = 0, i;
|
|
for (i = iSize-1; i >= 0; i-=3)
|
|
{
|
|
if (i == 1)
|
|
{
|
|
if (((iSize/3)%2) == 1) bitString = (input[i--] << 8) + (input[i--]);
|
|
else bitString = (input[i--] << 8) + (input[i--] << 4);
|
|
}
|
|
else if (i == 0)
|
|
{
|
|
if (((iSize/3)%2) == 1) bitString = input[i--] << 8;
|
|
else bitString = input[i--] << 4;
|
|
}
|
|
else bitString = (input[i] << 8) + (input[i-1] << 4) + (input[i-2]);
|
|
|
|
output[u++] = base64Table[(bitString & 0b111111_000000)>>6];
|
|
output[u++] = base64Table[bitString & 0b000000_111111];
|
|
}
|
|
|
|
for (new a = 0; a < (u%4); a++)
|
|
{
|
|
output[u++] = '=';
|
|
}
|
|
output[u++] = 0;
|
|
return u;
|
|
} |