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;
 | |
| } |