PublicKey cs using System using System Collections Generic using Syste

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
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();
}
}
}