PublicKey.cs using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using Mono.Math; namespace YamRsa { class PublicKey { private const int HEX = 16; public readonly BigInteger Module; public readonly BigInteger Exponent; public PublicKey(BigInteger m, BigInteger e) { Module = m; Exponent = e; } /// /// Requires 0 <= plain < Module /// /// public BigInteger Encrypt(BigInteger plain) { return plain.ModPow(Exponent, Module); } public static PublicKey FromString(string me) { var pair = me.Split(new[] {'#'}, 2); if (pair.Length != 2) throw new ArgumentException("Wrong format", "me"); return new PublicKey(ParseHex(pair[0]), ParseHex(pair[1])); } private static BigInteger ParseHex(IEnumerable hexString) { return hexString.Aggregate(new BigInteger(), (integer, @char) => integer*HEX + int.Parse(new string(new[] {@char}), NumberStyles.AllowHexSpecifier)); } public override string ToString() { return string.Format("{0}#{1}", Module.ToString(HEX), Exponent.ToString(HEX)); } } } CryptoProviderRSA.cs using System; using System.Linq; using Mono.Math; namespace YamRsa { public class CryptoProviderRSA { private PublicKey _publicKey; public void ImportPublicKey(string key) { _publicKey = PublicKey.FromString(key); } private const int MAX_CRYPT_BITS = 1024; public byte[] Encrypt(byte[] data) { // must ensure that any data block would be < key's modulus // hence -1 int portionLen = (_publicKey.Module.BitCount() - 1) / 8; var prevCrypted = new byte[portionLen]; return Enumerable .Range(0, ((data.Length - 1) / portionLen) + 1) .Select(i => data.Skip(i * portionLen).Take(portionLen)) .SelectMany(portion => { var portbuf = portion.Select((b, i) => (byte)(b ^ prevCrypted[i])).ToArray(); var cp = _publicKey.Encrypt(new BigInteger(portbuf)).GetBytes(); var length = Math.Min(portbuf.Length, cp.Length); Array.Copy(cp, prevCrypted, length); Array.Clear(prevCrypted, length, prevCrypted.Length - length); return BitConverter.GetBytes((ushort)portbuf.Length) .Concat(BitConverter.GetBytes((ushort)cp.Length)) .Concat(cp) .ToArray(); }) .ToArray(); } } } Program.cs using System; using System.Linq; using System.Text; namespace YamRsa { class Program { static void Main(string[] args) { var rsa = new CryptoProviderRSA(); rsa.ImportPublicKey(args[0]); string data = @""; var encoded = rsa.Encrypt(Encoding.ASCII.GetBytes(data)); Console.WriteLine(Convert.ToBase64String(encoded)); Console.ReadLine(); } } }