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 Buffer.BlockCopy(this.modulus, 0, this.publicKey, 2, c);
140 Buffer.BlockCopy(this.exponent, 0, this.publicKey, c + 2, d);
142 this.publicKeyBase64 = Convert.ToBase64String(this.publicKey);
182 if (this.keySize < 768)
184 else if (this.keySize < 1024)
186 else if (this.keySize < 2048)
188 else if (this.keySize < 3072)
190 else if (this.keySize < 4096)
192 else if (this.keySize < 7680)
194 else if (this.keySize < 15360)
225 throw new ArgumentException(
"Key strength too high.", nameof(
SecurityStrength));
239 RSAParameters P =
new RSAParameters();
240 string s = Encoding.ASCII.GetString(Secret);
241 string[] Parts = s.Split(
',');
246 foreach (
string Part
in Parts)
248 i = Part.IndexOf(
'=');
253 Value = Convert.FromBase64String(Part[(i + 1)..]);
257 case "D": P.D = Value;
break;
258 case "DP": P.DP = Value;
break;
259 case "DQ": P.DQ = Value;
break;
260 case "Exponent": P.Exponent = Value;
break;
261 case "InverseQ": P.InverseQ = Value;
break;
262 case "Modulus": P.Modulus = Value;
break;
263 case "P": P.P = Value;
break;
264 case "Q": P.Q = Value;
break;
268 RSA Rsa = RSA.Create();
269 Rsa.ImportParameters(P);
281 RSAParameters P = this.rsa.ExportParameters(Private);
282 StringBuilder sb =
new StringBuilder();
284 sb.Append(
"Exponent=");
285 sb.Append(Convert.ToBase64String(P.Exponent));
286 sb.Append(
",Modulus=");
287 sb.Append(Convert.ToBase64String(P.Modulus));
291 sb.Append(Convert.ToBase64String(P.D));
293 sb.Append(Convert.ToBase64String(P.DP));
295 sb.Append(Convert.ToBase64String(P.DQ));
296 sb.Append(
",InverseQ=");
297 sb.Append(Convert.ToBase64String(P.InverseQ));
299 sb.Append(Convert.ToBase64String(P.P));
301 sb.Append(Convert.ToBase64String(P.P));
304 return Encoding.ASCII.GetBytes(sb.ToString());
315 throw new ArgumentException(
"Invalid public key.", nameof(
PublicKey));
323 throw new ArgumentException(
"Invalid public key.", nameof(
PublicKey));
325 int ExpSize = PublicKey.Length - 2 - ModSize;
327 throw new ArgumentException(
"Invalid public key.", nameof(
PublicKey));
329 byte[]
Modulus =
new byte[ModSize];
330 byte[]
Exponent =
new byte[ExpSize];
358 if (!(RemoteEndpoint is
RsaEndpoint RemoteRsaEndpoint))
359 throw new InvalidOperationException(
"Remote endpoint is not an RSA endpoint.");
363 lock (RemoteRsaEndpoint.rsa)
365 CipherText = RemoteRsaEndpoint.rsa.Encrypt(Secret, RSAEncryptionPadding.OaepSHA256);
383 return this.rsa.Decrypt(CipherText, RSAEncryptionPadding.OaepSHA256);
397 public override byte[]
Sign(
byte[] Data)
399 return this.rsa.SignData(Data, HashAlgorithmName.SHA256, RSASignaturePadding.Pss);
407 public override byte[]
Sign(Stream Data)
409 return this.rsa.SignData(Data, HashAlgorithmName.SHA256, RSASignaturePadding.Pss);
418 public override bool Verify(
byte[] Data,
byte[] Signature)
420 return RsaEndpoint.
Verify(Data, Signature, this.keySize, this.modulus, this.exponent);
429 public override bool Verify(Stream Data,
byte[] Signature)
431 return RsaEndpoint.
Verify(Data, Signature, this.keySize, this.modulus, this.exponent);
445 int d = PublicKey.Length - c;
447 throw new ArgumentException(
"Invalid public key.", nameof(
PublicKey));
469 int d = PublicKey.Length - c;
471 throw new ArgumentException(
"Invalid public key.", nameof(
PublicKey));
493 using RSA Rsa = CreateRSA(
KeySize);
494 RSAParameters P =
new RSAParameters()
500 Rsa.ImportParameters(P);
502 return Rsa.VerifyData(Data, Signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pss);
516 using RSA Rsa = CreateRSA(
KeySize);
517 RSAParameters P =
new RSAParameters()
523 Rsa.ImportParameters(P);
525 return Rsa.VerifyData(Data, Signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pss);
531 public override bool Slow =>
true;
538 this.modulusBase64.Equals(
RsaEndpoint.modulusBase64) &&
539 this.exponentBase64.Equals(
RsaEndpoint.exponentBase64);
545 int Result = this.keySize.GetHashCode();
546 Result ^= Result << 5 ^ this.modulusBase64.GetHashCode();
547 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 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.
override byte[] GetSharedSecretForEncryption(IE2eEndpoint RemoteEndpoint, IE2eSymmetricCipher Cipher, out byte[] CipherText)
Gets a shared secret for encryption, and optionally a corresponding cipher text.
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 bool SharedSecretUseCipherText
If the recipient needs a cipher text to generate the same shared secret.
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 byte[] GetSharedSecretForDecryption(IE2eEndpoint RemoteEndpoint, byte[] CipherText)
Gets a shared secret for decryption.
RsaEndpoint(RSA Rsa)
RSA / AES-256 hybrid cipher.
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.
byte[] GenerateKey()
Generates a new key. Used when the asymmetric cipher cannot calculate a shared secret.
IE2eSymmetricCipher CreteNew()
Creates a new symmetric cipher object with the same settings as the current object.