3using System.Security.Cryptography;
15 private readonly
byte[] modulus;
16 private readonly
byte[] exponent;
17 private readonly
int keySize;
18 private byte[] publicKey;
19 private string publicKeyBase64;
20 private string modulusBase64;
21 private string exponentBase64;
46 : this(CreateRSA(
KeySize), SymmetricCipher)
50 private static RSA CreateRSA(
int KeySize)
52 RSA Result = RSA.Create();
75 : base(SymmetricCipher)
79 RSAParameters P = this.rsa.ExportParameters(
false);
81 this.keySize = this.rsa.KeySize;
82 this.modulus = P.Modulus;
83 this.exponent = P.Exponent;
108 : base(SymmetricCipher)
116 RSAParameters Param =
new RSAParameters()
122 this.rsa.ImportParameters(Param);
129 this.modulusBase64 = Convert.ToBase64String(this.modulus);
130 this.exponentBase64 = Convert.ToBase64String(this.exponent);
132 int c = this.modulus.Length;
133 int d = this.exponent.Length;
135 this.publicKey =
new byte[2 + c + d];
137 this.publicKey[0] = (byte)(this.keySize);
138 this.publicKey[1] = (byte)(this.keySize >> 8);
139 Array.Copy(this.modulus, 0, this.publicKey, 2, c);
140 Array.Copy(this.exponent, 0, this.publicKey, c + 2, d);
142 this.publicKeyBase64 = Convert.ToBase64String(this.publicKey);
182 if (this.keySize < 1024)
184 else if (this.keySize < 2048)
186 else if (this.keySize < 3072)
188 else if (this.keySize < 7680)
190 else if (this.keySize < 15360)
217 throw new ArgumentException(
"Key strength too high.", nameof(
SecurityStrength));
231 RSAParameters P =
new RSAParameters();
232 string s = Encoding.ASCII.GetString(Secret);
233 string[] Parts = s.Split(
',');
238 foreach (
string Part
in Parts)
240 i = Part.IndexOf(
'=');
244 Name = Part.Substring(0, i);
245 Value = Convert.FromBase64String(Part.Substring(i + 1));
249 case "D": P.D = Value;
break;
250 case "DP": P.DP = Value;
break;
251 case "DQ": P.DQ = Value;
break;
252 case "Exponent": P.Exponent = Value;
break;
253 case "InverseQ": P.InverseQ = Value;
break;
254 case "Modulus": P.Modulus = Value;
break;
255 case "P": P.P = Value;
break;
256 case "Q": P.Q = Value;
break;
260 RSA Rsa = RSA.Create();
261 Rsa.ImportParameters(P);
273 RSAParameters P = this.rsa.ExportParameters(Private);
274 StringBuilder sb =
new StringBuilder();
276 sb.Append(
"Exponent=");
277 sb.Append(Convert.ToBase64String(P.Exponent));
278 sb.Append(
",Modulus=");
279 sb.Append(Convert.ToBase64String(P.Modulus));
283 sb.Append(Convert.ToBase64String(P.D));
285 sb.Append(Convert.ToBase64String(P.DP));
287 sb.Append(Convert.ToBase64String(P.DQ));
288 sb.Append(
",InverseQ=");
289 sb.Append(Convert.ToBase64String(P.InverseQ));
291 sb.Append(Convert.ToBase64String(P.P));
293 sb.Append(Convert.ToBase64String(P.P));
296 return Encoding.ASCII.GetBytes(sb.ToString());
307 throw new ArgumentException(
"Invalid public key.", nameof(
PublicKey));
315 throw new ArgumentException(
"Invalid public key.", nameof(
PublicKey));
317 int ExpSize = PublicKey.Length - 2 - ModSize;
319 throw new ArgumentException(
"Invalid public key.", nameof(
PublicKey));
321 byte[]
Modulus =
new byte[ModSize];
322 byte[]
Exponent =
new byte[ExpSize];
351 throw new NotSupportedException(
"Getting shared secrets using RSA not supported.");
363 return this.rsa.Encrypt(Secret, RSAEncryptionPadding.OaepSHA256);
376 return this.rsa.Decrypt(Secret, RSAEncryptionPadding.OaepSHA256);
385 public override byte[]
Sign(
byte[] Data)
387 return this.rsa.SignData(Data, HashAlgorithmName.SHA256, RSASignaturePadding.Pss);
395 public override byte[]
Sign(Stream Data)
397 return this.rsa.SignData(Data, HashAlgorithmName.SHA256, RSASignaturePadding.Pss);
406 public override bool Verify(
byte[] Data,
byte[] Signature)
408 return RsaEndpoint.
Verify(Data, Signature, this.keySize, this.modulus, this.exponent);
417 public override bool Verify(Stream Data,
byte[] Signature)
419 return RsaEndpoint.
Verify(Data, Signature, this.keySize, this.modulus, this.exponent);
433 int d = PublicKey.Length - c;
435 throw new ArgumentException(
"Invalid public key.", nameof(
PublicKey));
457 int d = PublicKey.Length - c;
459 throw new ArgumentException(
"Invalid public key.", nameof(
PublicKey));
481 using (RSA Rsa = CreateRSA(
KeySize))
483 RSAParameters P =
new RSAParameters()
489 Rsa.ImportParameters(P);
491 return Rsa.VerifyData(Data, Signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pss);
506 using (RSA Rsa = CreateRSA(
KeySize))
508 RSAParameters P =
new RSAParameters()
514 Rsa.ImportParameters(P);
516 return Rsa.VerifyData(Data, Signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pss);
523 public override bool Slow =>
true;
530 this.modulusBase64.Equals(
RsaEndpoint.modulusBase64) &&
531 this.exponentBase64.Equals(
RsaEndpoint.exponentBase64);
537 int Result = this.keySize.GetHashCode();
538 Result ^= Result << 5 ^ this.modulusBase64.GetHashCode();
539 Result ^= Result << 5 ^ this.exponentBase64.GetHashCode();
Abstract base class for End-to-End encryption schemes.
virtual IE2eSymmetricCipher DefaultSymmetricCipher
Default symmetric cipher.
RSA / AES-256 hybrid cipher.
override byte[] Sign(Stream Data)
Signs binary data using the local private key.
RsaEndpoint(int KeySize, byte[] Modulus, byte[] Exponent)
RSA / AES-256 hybrid cipher.
override byte[] EncryptSecret(byte[] Secret)
Encrypts a secret. Used if shared secrets cannot be calculated.
override byte[] DecryptSecret(byte[] Secret)
Decrypts a secret. Used if shared secrets cannot be calculated.
override int SecurityStrength
Security strength of End-to-End encryption scheme.
byte[] Modulus
Modulus of RSA public key.
override string PublicKeyBase64
Remote public key, as a Base64 string.
override IE2eEndpoint CreatePublic(byte[] PublicKey)
Creates a new endpoint given a public key.
override void Dispose()
IDisposable.Dispose
override bool Verify(Stream Data, byte[] Signature)
Verifies a signature.
RsaEndpoint()
RSA / AES-256 hybrid cipher.
byte[] Export(bool Private)
Exports information from the encryption object.
RsaEndpoint(int KeySize)
RSA / AES-256 hybrid cipher.
override bool Slow
If implementation is slow, compared to other options.
override bool Verify(byte[] Data, byte[] Signature)
Verifies a signature.
override IE2eEndpoint Create(int SecurityStrength)
Creates a new key.
static bool Verify(byte[] Data, byte[] Signature, int KeySize, byte[] Modulus, byte[] Exponent)
Verifies a signature.
override int GetHashCode()
override byte[] Sign(byte[] Data)
Signs binary data using the local private key.
byte[] Exponent
Exponent of RSA public key.
override string LocalName
Local name of the E2E encryption scheme
static bool Verify(byte[] Data, byte[] Signature, int KeySize, byte[] PublicKey)
Verifies a signature.
RsaEndpoint(int KeySize, IE2eSymmetricCipher SymmetricCipher)
RSA / AES-256 hybrid cipher.
override bool Equals(object obj)
RsaEndpoint(int KeySize, byte[] Modulus, byte[] Exponent, IE2eSymmetricCipher SymmetricCipher)
RSA / AES-256 hybrid cipher.
static bool Verify(Stream Data, byte[] Signature, int KeySize, byte[] PublicKey)
Verifies a signature.
RsaEndpoint(RSA Rsa, IE2eSymmetricCipher SymmetricCipher)
RSA / AES-256 hybrid cipher.
override IE2eEndpoint CreatePrivate(byte[] Secret)
Creates a new endpoint given a private key.
static bool Verify(Stream Data, byte[] Signature, int KeySize, byte[] Modulus, byte[] Exponent)
Verifies a signature.
override bool SupportsSharedSecrets
If shared secrets can be calculated from the endpoints keys.
RsaEndpoint(RSA Rsa)
RSA / AES-256 hybrid cipher.
override byte[] GetSharedSecret(IE2eEndpoint RemoteEndpoint)
Gets a shared secret
override byte[] PublicKey
Remote public key.
Implements support for the AES-256 cipher in hybrid End-to-End encryption schemes.
Abstract base class for End-to-End encryption schemes.
Interface for symmetric ciphers.
IE2eSymmetricCipher CreteNew()
Creates a new symmetric cipher object with the same settings as the current object.