I am trying to generate 64 HEX digits to be used as a AES 256 key with no success.
Can somebody point out the mistakes and a better way to generate the same.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Security.Cryptography;
namespace Test
{
public class Program
{
static System.Text.StringBuilder builder = new System.Text.StringBuilder();
public static void Main(string[] args)
{
String randomNumber = Convert.ToBase64String (GenerateRandomNumber(32));
Console.WriteLine(randomNumber);
string input = randomNumber;
char[] values = input.ToCharArray();
foreach (char letter in values)
{
// Get the integral value of the character.
int value = Convert.ToInt32(letter);
// Convert the decimal value to a hexadecimal value in string form.
string hexOutput = String.Format("{0:X}", value);
// Console.WriteLine("Hexadecimal value of {0} is {1}", letter, hexOutput);
builder.Append(hexOutput);
}
Console.WriteLine(builder);
}
public static byte[] GenerateRandomNumber(int length)
{
using (var randomNumberGenerator = new RNGCryptoServiceProvider())
{
var randomNumber = new byte[length];
randomNumberGenerator.GetBytes(randomNumber);
return randomNumber;
}
}
}
}
Your biggest technical problem is that you used {0:X} when you meant {0:X2}. If the value is 10 the former produces "A" and the latter "0A". Since you've lost where all of the interior zeroes are your number isn't recoverable.
internal static string ByteArrayToHex(this byte[] bytes)
{
StringBuilder builder = new StringBuilder(bytes.Length * 2);
foreach (byte b in bytes)
{
builder.Append(b.ToString("X2"));
}
return builder.ToString();
}
(Code copied from https://github.com/dotnet/corefx/blob/7cad8486cbabbce0236bdf530e30db7036335524/src/Common/tests/System/Security/Cryptography/ByteUtils.cs#L37-L47)
But it's also pretty unclear why you're rerouting through Base64+ToCharArray+ToInt32. You're replacing values in the 0-255 range (bytes) with values in the [A-Za-z0-9/=+] rangeset, equivalent to 0-63 (Base64 and all); so you a) wouldn't have a very random key and b) it'll be too long.
I don't see why you need to convert it to a base64 string first. It could be as simple as this:
public class Program
{
public static void Main(string[] args)
{
var key = GenerateRandomNumber(32);
var hexEncodedKey = BitConverter.ToString(key).Replace("-", "");
Console.WriteLine(hexEncodedKey);
}
public static byte[] GenerateRandomNumber(int length)
{
using (var randomNumberGenerator = RandomNumberGenerator.Create())
{
var randomNumber = new byte[length];
randomNumberGenerator.GetBytes(randomNumber);
return randomNumber;
}
}
}
.NET framework already has a method Aes.GenerateKey() for generating symmetric keys, please look at this MSDN documentation: Aes class
Related
I have Java code example, of how verification code should be computed. And I have to convert Java code to C#.
First of all, code is computed as:
integer(SHA256(hash)[-2: -1]) mod 10000
Where we take SHA256 result, extract 2 rightmost bytes from it, interpret them as big-endian unsigned integer and take the last 4 digits in decimal for display.
Java code:
public static String calculate(byte[] documentHash) {
byte[] digest = DigestCalculator.calculateDigest(documentHash, HashType.SHA256);
ByteBuffer byteBuffer = ByteBuffer.wrap(digest);
int shortBytes = Short.SIZE / Byte.SIZE; // Short.BYTES in java 8
int rightMostBytesIndex = byteBuffer.limit() - shortBytes;
short twoRightmostBytes = byteBuffer.getShort(rightMostBytesIndex);
int positiveInteger = ((int) twoRightmostBytes) & 0xffff;
String code = String.valueOf(positiveInteger);
String paddedCode = "0000" + code;
return paddedCode.substring(code.length());
}
public static byte[] calculateDigest(byte[] dataToDigest, HashType hashType) {
String algorithmName = hashType.getAlgorithmName();
return DigestUtils.getDigest(algorithmName).digest(dataToDigest);
}
So int C# from Base64 string:
2afAxT+nH5qNYrfM+D7F6cKAaCKLLA23pj8ro3SksqwsdwmC3xTndKJotewzu7HlDy/DiqgkR+HXBiA0sW1x0Q==
should compute code equal to: 3676
Any ideas how to implement this?
class Program
{
static void Main(string[] args)
{
Console.WriteLine(GetCode("2afAxT+nH5qNYrfM+D7F6cKAaCKLLA23pj8ro3SksqwsdwmC3xTndKJotewzu7HlDy/DiqgkR+HXBiA0sW1x0Q=="));
}
public static string GetCode(string str)
{
var sha = System.Security.Cryptography.SHA256.Create();
var hash = sha.ComputeHash(Convert.FromBase64String(str));
var last2 = hash[^2..];
var intVal = ((int) last2[0]) * 0x0100 + ((int) last2[1]);
var digits = intVal % 10000;
return $"{digits:0000}";
}
}
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I wonder what is the best way to store binary data indexed by a string key into a single file.
This would be the circumstances I would be looking for:
Data indexed by a string key with variable length (max. 255 characters, ASCII only is fine).
Binary data has variable length (500 bytes up to 10 KB).
Amount of data stored < 5,000 entries.
In production only functions "GetDataByKey" & "GetAllKeys" needed and therefore should be fast.
Adding data is not used in production and can therefore be slow.
Is there any simple C# based library that would fit to those requirements?
I was looking at some NoSQL databases, but this seems to be a bit over the top for such a very simple data structure.
As only a small percentage of the data records are used during an application run I would prefer not to just read everything into memory on application start (e. g. using serialization), but instead just read the entries from the file that are really needed during runtime.
Any ideas or tips would be much appreciated, thanks!
Use Binaryformater like code below :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.Serialization.Formatters.Binary;
using System.Xml.Serialization;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.bin";
static void Main(string[] args)
{
Read_Write readWrite = new Read_Write();
readWrite.CreateData(1000);
readWrite.WriteData(FILENAME);
Data data = readWrite.GetRecord(FILENAME, "101");
}
}
[Serializable()]
[XmlRoot(ElementName="ABC")]
public struct Data
{
public byte[] name;
public byte[] data;
}
public class Read_Write
{
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
static extern int memcmp(byte[] b1, byte[] b2, long count);
const int MIN_SIZE = 500;
const int MAX_SIZE = 10000;
public List<Data> data { get; set; }
Dictionary<string, Data> dict = new Dictionary<string, Data>();
public void CreateData(int numberRecords)
{
data = new List<Data>();
for (int i = 0; i < numberRecords; i++)
{
Data newData = new Data();
string name = i.ToString() + '\0'; //null terminate string
newData.name = Encoding.UTF8.GetBytes(name);
Random rand = new Random();
int size = rand.Next(MIN_SIZE, MAX_SIZE);
newData.data = Enumerable.Range(0, size).Select(x => (byte)(rand.Next(0, 0xFF) & 0xFF)).ToArray();
data.Add(newData);
}
}
public void WriteData(string filename)
{
Stream writer = File.OpenWrite(filename);
//write number of records
byte[] numberOfRecords = BitConverter.GetBytes((int)data.Count());
writer.Write(numberOfRecords, 0, 4);
foreach (Data d in data)
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(writer, d);
}
writer.Flush();
writer.Close();
}
public Data GetRecord(string filename, string name)
{
Data record = new Data();
Stream reader = File.OpenRead(filename);
byte[] numberOfRecords = new byte[4];
reader.Read(numberOfRecords, 0, 4);
int records = BitConverter.ToInt32(numberOfRecords, 0);
DateTime start = DateTime.Now;
for(int i = 0; i < records; i++)
{
BinaryFormatter formatter = new BinaryFormatter();
Data d = (Data)formatter.Deserialize(reader);
//if (name == GetString(d.name))
//{
// record = d;
// break;
//}
}
DateTime end = DateTime.Now;
TimeSpan time = end - start;
reader.Close();
return record;
}
public string GetString(byte[] characters)
{
int length = characters.ToList().IndexOf(0x00);
return Encoding.UTF8.GetString(characters, 0, length);
}
}
}
As there seems not to be a solution/library available for this yet (probably, because the problem is just too simple to share it ;-) ), I've build a small class myself.
In case somebody else needs the same, that's the way I store this string key based binary data now:
internal class BinaryKeyStorage
{
private const string FILE_PATH = #"data.bin";
private static MemoryMappedFile _memoryFile;
private static MemoryMappedViewStream _memoryFileStream;
private static Dictionary<string, Entry> _index;
private class Entry
{
public Entry(int position, int length)
{
Position = position;
Length = length;
}
public int Position { get; }
public int Length { get; }
}
public static void CreateFile(Dictionary<string, byte[]> keyValues)
{
// 4 bytes for int count of entries
// and per entry:
// - string length + 1 byte for string prefix
// - 2x4 bytes for int address start and length
var headerLength = 4 + keyValues.Keys.Sum(dataKey => dataKey.Length + 9);
var nextStartPosition = headerLength;
using (var binaryWriter = new BinaryWriter(File.Open(FILE_PATH, FileMode.Create)))
{
binaryWriter.Write(keyValues.Count);
// writing header
foreach (var keyValue in keyValues)
{
binaryWriter.Write(keyValue.Key);
binaryWriter.Write(nextStartPosition);
binaryWriter.Write(keyValue.Value.Length);
nextStartPosition += keyValue.Value.Length;
}
// writing data
foreach (var keyValue in keyValues)
{
binaryWriter.Write(keyValue.Value);
}
}
}
public static List<string> GetAllKeys()
{
InitializeIndexIfNeeded();
return _index.Keys.ToList();
}
public static byte[] GetData(string key)
{
InitializeIndexIfNeeded();
var entry = _index[key];
_memoryFileStream.Seek(entry.Position, SeekOrigin.Begin);
var data = new byte[entry.Length];
_memoryFileStream.Read(data, 0, data.Length);
return data;
}
private static void InitializeIndexIfNeeded()
{
if (_memoryFile != null) return;
_memoryFile = MemoryMappedFile.CreateFromFile(FILE_PATH, FileMode.Open);
_memoryFileStream = _memoryFile.CreateViewStream();
_index = new Dictionary<string, Entry>();
using (var binaryReader = new BinaryReader(_memoryFileStream, Encoding.Default, true))
{
var count = binaryReader.ReadInt32();
for (var i = 0; i < count; i++)
{
var dataKey = binaryReader.ReadString();
var dataPosition = binaryReader.ReadInt32();
var dataLength = binaryReader.ReadInt32();
_index.Add(dataKey, new Entry(dataPosition, dataLength));
}
}
}
}
It just caches the file header/index (the string keys together with the position/length of the data) in memory, the actual data is read directly from the memory mapped file only if needed.
I am trying to write a console application that will take data as input and split it in to two
example: if i pass a value 0x00000000A0DB383E as input my output should be look like below:
var LowerValue = 0x00000000A0DB0000 (last 2 bytes 383E (index 14-17) replaced with 0000)
var UpperValue = 0x000000000000383E (middle 2 bytes A0DB (index 10-13) replaced with 0000)
So far i have tried below but dont know how to proceed further. Any help will be highly appreciated
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace SplitFunction
{
class Program
{
static void Main(string[] args)
{
byte[] rawValue = BitConverter.GetBytes(0x00000000A0DB383E);
SplitData(rawValue);
Console.ReadKey();
}
public static byte[] SplitDta(byte[] input)
{
byte[] lowerValues = new byte[8];
Array.Copy(input, 0, lowerValues, 4, 4);
foreach(var lowerValue in lowerValues)
Console.WriteLine(lowerValue);
return lowerValues;
}
}
}
Rather than copying & zeroing individual array elements, use masking to create new arrays directly. Something like this :
long input = 0x0000000A0DB383EL;
byte[] rawValue = BitConverter.GetBytes(input);
byte[] lowValue = BitConverter.GetBytes(input & 0x000000000000FFFF);
byte[] highValue = BitConverter.GetBytes(input & 0x00000000FFFF0000);
if you want the values in order high byte to low byte - then reverse them
byte[] rawValue = Array.Reverse(BitConverter.GetBytes(input));
byte[] lowValue = Array.Reverse(BitConverter.GetBytes(input & 0x000000000000FFFF));
byte[] highValue = Array.Reverse(BitConverter.GetBytes(input & 0x00000000FFFF0000));
if you simply want the long value rather than an array
long lowValue = input & 0x000000000000FFFF;
long highValue = input & 0x00000000FFFF0000;
I am trying to follow the instructions on deriving the WIF of a Hex bitcoin private key from - https://en.bitcoin.it/wiki/Wallet_import_format
However, when I try to hash the string (including 0x80 byte) I get different result than the expected.
I should have gotten 8147786C4D15106333BF278D71DADAF1079EF2D2440A4DDE37D747DED5403592.
Instead I receive e2e4146a36e9c455cf95a4f259f162c353cd419cc3fd0e69ae36d7d1b6cd2c09.
I read extensively on google and I understood that I should convert the string to binaries. I did, and then hashed the char array from those binaries to the same result.
Code is now working thanks to #Heinan Cabouly and #JaredPar
Here is the working code:
using System;
using System.Security.Cryptography;
using System.Text;
using System.Linq;
namespace Base58Encode
{
internal class Program
{
public static string Str = "800C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D";
public static byte[] Bytes;
public static void Main()
{
Bytes = StringToByteArray(Str);
SHA256Managed sha = new SHA256Managed();
string hashstr = String.Empty;
byte[] encrypt = sha.ComputeHash(Bytes);
foreach (byte b in encrypt)
{
hashstr += b.ToString("x2");
}
Console.WriteLine(hashstr);
//prints e2e4146a36e9c455cf95a4f259f162c353cd419cc3fd0e69ae36d7d1b6cd2c09
//instead of 8147786C4D15106333BF278D71DADAF1079EF2D2440A4DDE37D747DED5403592
Console.ReadLine();
}
public static byte[] StringToByteArray(string hex)
{
return Enumerable.Range(0, hex.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
.ToArray();
}
}
}
This is how to hash a hex string SHA-256 in C#.
Thanks to all! Helped me out a lot!
As said here before me, the method you used for conversion isn't suitable. You can use this method (taken from stackoverflow by #JaredPar):
public static byte[] StringToByteArray(string hex) {
return Enumerable.Range(0, hex.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
.ToArray();
}
You call this function with your str (which represents the HEX string), and it will return the HEX representation.
From there, you can continue with your function as written.
I am trying to implement my own RSA encryption engine. Given these RSA algorithm values:
p = 61. // A prime number.
q = 53. // Also a prime number.
n = 3233. // p * q.
totient = 3120. // (p - 1) * (q - 1)
e = 991. // Co-prime to the totient (co-prime to 3120).
d = 1231. // d * e = 1219921, which is equal to the relation where 1 + k * totient = 1219921 when k = 391.
I am trying to write a method to encrypt each byte in a string and return back an encrypted string:
public string Encrypt(string m, Encoding encoding)
{
byte[] bytes = encoding.GetBytes(m);
for (int i = 0; i < bytes.Length; i++)
{
bytes[i] = (byte)BigInteger.ModPow(bytes[i], e, n);
}
string encryptedString = encoding.GetString(bytes);
Console.WriteLine("Encrypted {0} as {1}.", m, encryptedString);
return encryptedString;
}
The obvious issue here is that BigInteger.ModPow(bytes[i], e, n) may be too large to fit into a byte-space; it could result in values over 8 bits in size. How do you get around this issue while still being able to decrypt an encrypted string of bytes back into a regular string?
Update: Even encrypting from byte[] to byte[], you reach a case where encrypting that byte using the RSA algorithm goes beyond the size limit of a byte:
public byte[] Encrypt(string m, Encoding encoding)
{
byte[] bytes = encoding.GetBytes(m);
for (int i = 0; i < bytes.Length; i++)
{
bytes[i] = (byte)BigInteger.ModPow(bytes[i], e, n);
}
return bytes;
}
Update: My issue is that encryption would cause a greater number of bytes than the initial input string had:
public byte[] Encrypt(string m, Encoding encoding)
{
byte[] bytes = encoding.GetBytes(m);
byte[] returnBytes = new byte[0];
for (int i = 0; i < bytes.Length; i++)
{
byte[] result = BigInteger.ModPow(bytes[i], (BigInteger)e, n).ToByteArray();
int preSize = returnBytes.Length;
Array.Resize(ref returnBytes, returnBytes.Length + result.Length);
result.CopyTo(returnBytes, preSize);
}
return returnBytes;
}
public string Decrypt(byte[] c, Encoding encoding)
{
byte[] returnBytes = new byte[0];
for (int i = 0; i < c.Length; i++)
{
byte[] result = BigInteger.ModPow(c[i], d, n).ToByteArray();
int preSize = returnBytes.Length;
Array.Resize(ref returnBytes, returnBytes.Length + result.Length);
result.CopyTo(returnBytes, preSize);
}
string decryptedString = encoding.GetString(returnBytes);
return decryptedString;
}
If you ran this code like this:
byte[] encryptedBytes = engine.Encrypt("Hello, world.", Encoding.UTF8);
Console.WriteLine(engine.Decrypt(encryptedBytes, Encoding.UTF8));
The output would be this:
?♥D
?♥→☻►♦→☻►♦oD♦8? ?♠oj?♠→☻►♦;♂?♠♂♠?♠
Obviously, the output is not the original string because I can't just try decrypting each byte at a time, since sometimes two or more bytes of the cypher-text represent the value of one integer that I need to decrypt back to one byte of the original string...so I want to know what the standard mechanism for handling this is.
Your basic code for encrypting and decrypting each byte - the call to ModPow - is working, but you're going about the "splitting the message up and encrypting each piece" inappropriately.
To show that the ModPow part - i.e. the maths - is fine, here's code based on yours, which encrypts a string to a BigInteger[] and back:
using System;
using System.Linq;
using System.Numerics;
using System.Text;
class Test
{
const int p = 61;
const int q = 53;
const int n = 3233;
const int totient = 3120;
const int e = 991;
const int d = 1231;
static void Main()
{
var encrypted = Encrypt("Hello, world.", Encoding.UTF8);
var decrypted = Decrypt(encrypted, Encoding.UTF8);
Console.WriteLine(decrypted);
}
static BigInteger[] Encrypt(string text, Encoding encoding)
{
byte[] bytes = encoding.GetBytes(text);
return bytes.Select(b => BigInteger.ModPow(b, (BigInteger)e, n))
.ToArray();
}
static string Decrypt(BigInteger[] encrypted, Encoding encoding)
{
byte[] bytes = encrypted.Select(bi => (byte) BigInteger.ModPow(bi, d, n))
.ToArray();
return encoding.GetString(bytes);
}
}
Next you need to read more about how a byte[] is encrypted into another byte[] using RSA, including all the different padding schemes etc. There's a lot more to it than just calling ModPow on each byte.
But to reiterate, you should not be doing this to end up with a production RSA implementation. The chances of you doing that without any security flaws are very slim indeed. It's fine to do this for academic interest, to learn more about the principles of cryptography, but leave the real implementations to experts. (I'm far from an expert in this field - there's no way I'd start implementing my own encryption...)
Note: I updated this answer. Please scroll down to the update for how it should actually be implemented because this first way of doing it is not the correct way of doing RSA encryption.
One way I can think to do it is like this (but may not be compliant to standards), and also, note this does not pad:
public byte[] Encrypt(string m, Encoding encoding)
{
byte[] bytes = encoding.GetBytes(m);
byte[] returnBytes = new byte[0];
for (int i = 0; i < bytes.Length; i++)
{
byte[] result = BigInteger.ModPow(bytes[i], (BigInteger)e, n).ToByteArray();
int preSize = returnBytes.Length;
Array.Resize(ref returnBytes, returnBytes.Length + result.Length + 1);
(new byte[] { (byte)(result.Length) }).CopyTo(returnBytes, preSize);
result.CopyTo(returnBytes, preSize + 1);
}
return returnBytes;
}
public string Decrypt(byte[] c, Encoding encoding)
{
byte[] returnBytes = new byte[0];
for (int i = 0; i < c.Length; i++)
{
int dataLength = (int)c[i];
byte[] result = new byte[dataLength];
for (int j = 0; j < dataLength; j++)
{
i++;
result[j] = c[i];
}
BigInteger integer = new BigInteger(result);
byte[] integerResult = BigInteger.ModPow(integer, d, n).ToByteArray();
int preSize = returnBytes.Length;
Array.Resize(ref returnBytes, returnBytes.Length + integerResult.Length);
integerResult.CopyTo(returnBytes, preSize);
}
string decryptedString = encoding.GetString(returnBytes);
return decryptedString;
}
This has the potential of being cross-platform because you have the option of using a different datatype to represent e or n and pass it to a C# back-end service like that. Here is a test:
string stringToEncrypt = "Mary had a little lamb.";
Console.WriteLine("Encrypting the string: {0}", stringToEncrypt);
byte[] encryptedBytes = engine.Encrypt(stringToEncrypt, Encoding.UTF8);
Console.WriteLine("Encrypted text: {0}", Encoding.UTF8.GetString(encryptedBytes));
Console.WriteLine("Decrypted text: {0}", engine.Decrypt(encryptedBytes, Encoding.UTF8));
Output:
Encrypting the string: Mary had a little lamb.
Encrypted text: ☻6☻1♦☻j☻☻&♀☻g♦☻t☻☻1♦☻? ☻g♦☻1♦☻g♦☻?♥☻?☻☻7☺☻7☺☻?♥☻?♂☻g♦☻?♥☻1♦☻$☺☻
c ☻?☻
Decrypted text: Mary had a little lamb.
Update: Everything I said earlier is completely wrong in the implementation of RSA. Wrong, wrong, wrong! This is the correct way to do RSA encryption:
Convert your string to a BigInteger datatype.
Make sure your integer is smaller than the value of n that you've calculated for your algorithm, otherwise you won't be able to decypher it.
Encrypt the integer. RSA works on integer encryption only. This is clear.
Decrypt it from the encrypted integer.
I can't help but wonder that the BigInteger class was mostly created for cryptography.
As an example:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace BytePadder
{
class Program
{
const int p = 61;
const int q = 53;
const int n = 3233;
const int totient = 3120;
const int e = 991;
const int d = 1231;
static void Main(string[] args)
{
// ---------------------- RSA Example I ----------------------
// Shows how an integer gets encrypted and decrypted.
BigInteger integer = 1000;
BigInteger encryptedInteger = Encrypt(integer);
Console.WriteLine("Encrypted Integer: {0}", encryptedInteger);
BigInteger decryptedInteger = Decrypt(encryptedInteger);
Console.WriteLine("Decrypted Integer: {0}", decryptedInteger);
// --------------------- RSA Example II ----------------------
// Shows how a string gets encrypted and decrypted.
string unencryptedString = "A";
BigInteger integer2 = new BigInteger(Encoding.UTF8.GetBytes(unencryptedString));
Console.WriteLine("String as Integer: {0}", integer2);
BigInteger encryptedInteger2 = Encrypt(integer2);
Console.WriteLine("String as Encrypted Integer: {0}", encryptedInteger2);
BigInteger decryptedInteger2 = Decrypt(encryptedInteger2);
Console.WriteLine("String as Decrypted Integer: {0}", decryptedInteger2);
string decryptedIntegerAsString = Encoding.UTF8.GetString(decryptedInteger2.ToByteArray());
Console.WriteLine("Decrypted Integer as String: {0}", decryptedIntegerAsString);
Console.ReadLine();
}
static BigInteger Encrypt(BigInteger integer)
{
if (integer < n)
{
return BigInteger.ModPow(integer, e, n);
}
throw new Exception("The integer must be less than the value of n in order to be decypherable!");
}
static BigInteger Decrypt(BigInteger integer)
{
return BigInteger.ModPow(integer, d, n);
}
}
}
Example output:
Encrypted Integer: 1989
Decrypted Integer: 1000
String as Integer: 65
String as Encrypted Integer: 1834
String as Decrypted Integer: 65
Decrypted Integer as String: A
If you are looking to use RSA encryption in C# then you should not be attempting to build your own. For starters the prime numbers you have chosen are probably to small. P and Q are supposed to be large prime numbers.
You should check out some other question/answers:
how to use RSA to encrypt files (huge data) in C#
RSA Encryption of large data in C#
And other references:
http://msdn.microsoft.com/en-us/library/system.security.cryptography.rsacryptoserviceprovider.encrypt(v=vs.110).aspx
http://msdn.microsoft.com/en-us/library/system.security.cryptography.rsacryptoserviceprovider.aspx