/// <summary> /// Decrypts text /// </summary> /// <param name="text">TripleDES encrypted Base64url string.</param> /// <param name="container">Container which will contain the decryption result.</param> /// <returns>Returns the decrypted text, or null if decryption failed or if text is out of the valid time span.</returns> public DecryptionResult Decrypt(string text, T container) { var result = new DecryptionResult(); try { // Replace +/ with -_ and add = that were stripped by Url-safe Encryption byte[] input = Convert.FromBase64String(text.Replace('_', '/').Replace('-', '+').PadRight(text.Length + (4 - text.Length % 4) % 4, '=')); byte[] output = Transform(input, _desProvider.CreateDecryptor()); // how many bytes are needed to convert from typeof(long) int longAsBytesLength = BitConverter.GetBytes((long)0).Length; // first 8 bytes are the startOn ticks result.StartsOn = new DateTime(BitConverter.ToInt64(output, 0)); // next 8 bytes are the expiresOn ticks result.ExpiresOn = new DateTime(BitConverter.ToInt64(output, longAsBytesLength)); // The string starts after byte 16 result.RawText = _utf8Encoding.GetString(output, longAsBytesLength * 2, output.Length - longAsBytesLength * 2); result.Container = ToContainer(result.RawText, container); result.Exception = null; result.IsValid = true; return(result); } catch (Exception ex) { result.Exception = ex; result.Container = null; result.IsValid = false; result.RawText = string.Empty; return(result); } }
/// <summary> /// /// </summary> /// <param name="envelope"></param> /// <param name="ciphertext"></param> /// <returns></returns> /// <exception cref="InvalidMetadataMessageException"></exception> /// <exception cref="InvalidMetadataVersionException"></exception> /// <exception cref="ProtocolDuplicateMessageException"></exception> /// <exception cref="ProtocolUntrustedIdentityException"></exception> /// <exception cref="ProtocolLegacyMessageException"></exception> /// <exception cref="ProtocolInvalidKeyException"></exception> /// <exception cref="ProtocolInvalidVersionException"></exception> /// <exception cref="ProtocolInvalidMessageException"></exception> /// <exception cref="ProtocolInvalidKeyIdException"></exception> /// <exception cref="ProtocolNoSessionException"></exception> /// <exception cref="SelfSendException"></exception> private Plaintext Decrypt(SignalServiceEnvelope envelope, byte[] ciphertext) { try { byte[] paddedMessage; SignalServiceMetadata metadata; uint sessionVersion; if (!envelope.HasSource() && !envelope.IsUnidentifiedSender()) { throw new ProtocolInvalidMessageException(new InvalidMessageException("Non-UD envelope is missing a source!"), null, 0); } if (envelope.IsPreKeySignalMessage()) { SignalProtocolAddress sourceAddress = GetPreferredProtocolAddress(signalProtocolStore, envelope.GetSourceAddress(), envelope.GetSourceDevice()); SessionCipher sessionCipher = new SessionCipher(signalProtocolStore, sourceAddress); paddedMessage = sessionCipher.decrypt(new PreKeySignalMessage(ciphertext)); metadata = new SignalServiceMetadata(envelope.GetSourceAddress(), envelope.GetSourceDevice(), envelope.GetTimestamp(), false); sessionVersion = sessionCipher.getSessionVersion(); } else if (envelope.IsSignalMessage()) { SignalProtocolAddress sourceAddress = GetPreferredProtocolAddress(signalProtocolStore, envelope.GetSourceAddress(), envelope.GetSourceDevice()); SessionCipher sessionCipher = new SessionCipher(signalProtocolStore, sourceAddress); paddedMessage = sessionCipher.decrypt(new SignalMessage(ciphertext)); metadata = new SignalServiceMetadata(envelope.GetSourceAddress(), envelope.GetSourceDevice(), envelope.GetTimestamp(), false); sessionVersion = sessionCipher.getSessionVersion(); } else if (envelope.IsUnidentifiedSender()) { SealedSessionCipher sealedSessionCipher = new SealedSessionCipher(signalProtocolStore, localAddress.Uuid, localAddress.GetNumber(), 1); DecryptionResult result = sealedSessionCipher.Decrypt(certificateValidator !, ciphertext, (long)envelope.Envelope.ServerTimestamp); SignalServiceAddress resultAddress = new SignalServiceAddress(UuidUtil.Parse(result.SenderUuid), result.SenderE164); SignalProtocolAddress protocolAddress = GetPreferredProtocolAddress(signalProtocolStore, resultAddress, result.DeviceId); paddedMessage = result.PaddedMessage; metadata = new SignalServiceMetadata(resultAddress, result.DeviceId, envelope.GetTimestamp(), true); sessionVersion = (uint)sealedSessionCipher.GetSessionVersion(protocolAddress); } else { throw new InvalidMessageException($"Unknown type: {envelope.GetType()}"); } PushTransportDetails transportDetails = new PushTransportDetails(sessionVersion); byte[] data = transportDetails.GetStrippedPaddingMessageBody(paddedMessage); return(new Plaintext(metadata, data)); } catch (DuplicateMessageException e) { throw new ProtocolDuplicateMessageException(e, envelope.GetSourceIdentifier(), envelope.GetSourceDevice()); } catch (LegacyMessageException e) { throw new ProtocolLegacyMessageException(e, envelope.GetSourceIdentifier(), envelope.GetSourceDevice()); } catch (InvalidMessageException e) { throw new ProtocolInvalidMessageException(e, envelope.GetSourceIdentifier(), envelope.GetSourceDevice()); } catch (InvalidKeyIdException e) { throw new ProtocolInvalidKeyIdException(e, envelope.GetSourceIdentifier(), envelope.GetSourceDevice()); } catch (InvalidKeyException e) { throw new ProtocolInvalidKeyException(e, envelope.GetSourceIdentifier(), envelope.GetSourceDevice()); } catch (libsignal.exceptions.UntrustedIdentityException e) { throw new ProtocolUntrustedIdentityException(e, envelope.GetSourceIdentifier(), envelope.GetSourceDevice()); } catch (InvalidVersionException e) { throw new ProtocolInvalidVersionException(e, envelope.GetSourceIdentifier(), envelope.GetSourceDevice()); } catch (NoSessionException e) { throw new ProtocolNoSessionException(e, envelope.GetSourceIdentifier(), envelope.GetSourceDevice()); } }
public BadPassphraseException(DecryptionResult rst) { DecryptionResult = rst; }
static void Main(string[] args) { Context ctx = new Context(); if (ctx.Protocol != Protocol.OpenPGP) { ctx.SetEngineInfo(Protocol.OpenPGP, null, null); } Console.WriteLine("Search Bob's PGP key in the default keyring.."); String searchstr = "*****@*****.**"; IKeyStore keyring = ctx.KeyStore; // retrieve all keys that have Bob's email address Key[] keys = keyring.GetKeyList(searchstr, false); if (keys == null || keys.Length == 0) { Console.WriteLine("Cannot find Bob's PGP key {0} in your keyring.", searchstr); Console.WriteLine("You may want to create the PGP key by using the appropriate\n" + "sample in the Samples/ directory."); return; } // print a list of all returned keys foreach (Key key in keys) { if (key.Uid != null && key.Fingerprint != null) { Console.WriteLine("Found key {0} with fingerprint {1}", key.Uid.Name, key.Fingerprint); } } // we are going to use the first key in the list PgpKey bob = (PgpKey)keys[0]; if (bob.Uid == null || bob.Fingerprint == null) { throw new InvalidKeyException(); } // Create a sample string StringBuilder randomtext = new StringBuilder(); for (int i = 0; i < 80 * 6; i++) { randomtext.Append((char)(34 + i % 221)); } string secrettext = new string('+', 508) + " Die Gedanken sind frei " + new string('+', 508) + randomtext.ToString(); Console.WriteLine("Text to be encrypted:\n\n{0}", secrettext); // we want our string UTF8 encoded. UTF8Encoding utf8 = new UTF8Encoding(); // create a (dynamic) memory based data buffer to place the unencrypted (plain) text GpgmeData plain = new GpgmeMemoryData(); // set a filename for this data buffer plain.FileName = "my_document.txt"; BinaryWriter binwriter = new BinaryWriter(plain, utf8); // write our secret text to the memory buffer binwriter.Write(secrettext.ToCharArray()); binwriter.Flush(); // go to the beginning(!) binwriter.Seek(0, SeekOrigin.Begin); /////// ENCRYPT DATA /////// // we want or PGP encrypted data RADIX/BASE64 encoded. ctx.Armor = true; // create another (dynamic) memory based data buffer as destination GpgmeData cipher = new GpgmeMemoryData(); cipher.FileName = "my_document.txt"; Console.Write("Encrypt data for {0} ({1}).. ", bob.Uid.Name, bob.KeyId); EncryptionResult encrst = ctx.Encrypt( new Key[] { bob }, // encrypt data to Bob's key only EncryptFlags.AlwaysTrust, // trust our sample PGP key plain, // source buffer cipher); // destination buffer Console.WriteLine("done."); Console.WriteLine("Cipher text:"); // move cursor to the beginning cipher.Seek(0, SeekOrigin.Begin); /* Read cipher text from libgpgme's memory based buffer and print * it to the console screen. */ char[] buf; // the cipher text is UTF8 encoded BinaryReader binreader = new BinaryReader(cipher, utf8); while (true) { try { buf = binreader.ReadChars(255); if (buf.Length == 0) { break; } Console.Write(buf); } catch (EndOfStreamException) { break; } } /////// DECRYPT DATA /////// /* Set the password callback - needed if the user doesn't run * gpg-agent or any other password / pin-entry software. */ ctx.SetPassphraseFunction(new PassphraseDelegate(MyPassphraseCallback)); // go to the beginning(!) cipher.Seek(0, SeekOrigin.Begin); Console.Write("Decrypt data.. "); GpgmeData decryptedText = new GpgmeMemoryData(); DecryptionResult decrst = ctx.Decrypt( cipher, // source buffer decryptedText); // destination buffer Console.WriteLine("Done. Filename: \"{0}\" Recipients:", decrst.FileName); /* print out all recipients key ids (a PGP package can be * encrypted to various recipients). */ if (decrst.Recipients != null) { foreach (Recipient recp in decrst.Recipients) { Console.WriteLine("\tKey id {0} with {1} algorithm", recp.KeyId, Gpgme.GetPubkeyAlgoName(recp.KeyAlgorithm)); } } else { Console.WriteLine("\tNone"); } // TEST: Compare original data and decrypted data byte[] orig = new byte[255], cmp = new byte[255]; plain.Seek(0, SeekOrigin.Begin); decryptedText.Seek(0, SeekOrigin.Begin); while (true) { try { int a, b; a = plain.Read(orig, orig.Length); b = decryptedText.Read(cmp, cmp.Length); if (a != b) { throw new DecryptionFailedException("The two data buffers have different sizes."); } if (a == 0) { break; // everything okay - end of stream reached. } for (int i = 0; i < a; i++) { if (orig[i] != cmp[i]) { throw new DecryptionFailedException("The two data buffers differ at position " + i.ToString() + "."); } } } catch (EndOfStreamException) { throw new DecryptionFailedException("The two data buffers have different sizes."); } } // we do not want our GpgmeData buffers destroyed GC.KeepAlive(binwriter); GC.KeepAlive(binreader); /////// FILE BASED DATA BUFFERS /////// /////// ENCRYPT FILE /////// // Now let's use a file based data buffers // create the "source" file first and fill it with our sample text. Console.WriteLine("Create new file plainfile.txt."); File.WriteAllText("plainfile.txt", secrettext, utf8); GpgmeData plainfile = new GpgmeFileData( "plainfile.txt", FileMode.Open, FileAccess.Read); GpgmeData cipherfile = new GpgmeFileData( "cipherfile.asc", FileMode.Create, FileAccess.ReadWrite); Console.Write("Encrypt file plainfile.txt to cipherfile.asc.. "); encrst = ctx.Encrypt( new Key[] { bob }, EncryptFlags.AlwaysTrust, plainfile, cipherfile); Console.WriteLine("done."); plainfile.Close(); cipherfile.Close(); /////// DECRYPT FILE /////// //cipherfile = new GpgmeFileData("cipherfile.asc"); // load the file content into the system memory cipherfile = new GpgmeMemoryData("cipherfile.asc"); plainfile = new GpgmeFileData( "decrypted.txt", FileMode.Create, FileAccess.Write); Console.WriteLine("Decrypt file cipherfile.asc to decrypted.txt.. "); decrst = ctx.Decrypt( cipherfile, // source buffer plainfile); // destination buffer Console.WriteLine("Done. Filename: \"{0}\" Recipients:", decrst.FileName); /* print out all recipients key ids (a PGP package can be * encrypted to various recipients). */ if (decrst.Recipients != null) { foreach (Recipient recp in decrst.Recipients) { Console.WriteLine("\tKey id {0} with {1} algorithm", recp.KeyId, Gpgme.GetPubkeyAlgoName(recp.KeyAlgorithm)); } } else { Console.WriteLine("\tNone"); } cipherfile.Close(); plainfile.Close(); return; }
private async void DecryptButton_Click(object sender, EventArgs e) { var RemoveButtonState = DisableAllControls(); if (String.IsNullOrEmpty(TextInputEditor.Text) && fileData == null) { RestoreAllControls(RemoveButtonState); ShowDialog("Error", "Choose file or write/paste text to encrypt!"); DecryptButton.Enabled = false; return; } if (!String.IsNullOrEmpty(TextInputEditor.Text) && fileData != null) { RestoreAllControls(RemoveButtonState); ShowDialog("Error", "You can encrypt either file or text at a time!"); return; } string password = ""; try { password = await SecureStorage.GetAsync("AppPassword"); if (password == null) { ShowDialog("Error", "App's password is missing. Close application and try again!"); return; } } catch (Exception) { ShowDialog("Error", "App's password is missing. Close application and try again!"); return; } if (!PasswordSwitch.Checked) { if (String.IsNullOrEmpty(CustomPasswordEntry.Text) || CustomPasswordEntry.Text.Length < 6 || CustomPasswordEntry.Text.Length > 16) { RestoreAllControls(RemoveButtonState); ShowDialog("Error", "Custom Password length should be at least 6 and at most 16"); return; } password = CustomPasswordEntry.Text; } if (fileData == null) { DecryptionResult decryptionResult = null; await Task.Run(() => { decryptionResult = DecryptionService.DecryptText(TextInputEditor.Text, password); }); if (decryptionResult.Result) { ClipboardManager clipboardManager = (ClipboardManager)this.GetSystemService(Context.ClipboardService); clipboardManager.PrimaryClip = ClipData.NewPlainText("Decrypted Text", decryptionResult.DecryptedString); Toast.MakeText(this, "Decrypted text copied to clipboard", ToastLength.Long); fileData = null; RestoreAllControls(ViewStates.Invisible); RemoveButton_Click(null, null); TextInputEditor.Text = String.Empty; CustomPasswordEntry.Text = String.Empty; PasswordSwitch.Checked = true; ShowDialog("Decrypted Text", decryptionResult.DecryptedString); } else { RestoreAllControls(RemoveButtonState); ShowDialog("Failed", "Decryption failed. This text can not be encrypted. Error: \"" + decryptionResult.Error + "\""); } } else { DecryptionResult decryptionResult = null; await Task.Run(() => { decryptionResult = DecryptionService.DecryptFile(fileData, password); }); if (decryptionResult.Result) { RestoreAllControls(ViewStates.Invisible); ShowDialog("Success", "File decrypted. Decrypted filename is \"" + decryptionResult.DecryptedString + "\" and stored at \"Crypto App" + "\" folder."); fileData = null; RemoveButton_Click(null, null); TextInputEditor.Text = String.Empty; CustomPasswordEntry.Text = String.Empty; PasswordSwitch.Checked = true; } else if (decryptionResult.Result == false && decryptionResult.Error == "Password") { RestoreAllControls(RemoveButtonState); PasswordSwitch.Checked = false; CustomPasswordEntry.Visibility = ViewStates.Visible; ShowDialog("Error", "Password is wrong. Enter correct password to decrypt."); return; } else { RestoreAllControls(RemoveButtonState); ShowDialog("Failed", "File decryption failed. This file can not be decrypted.Error: \"" + decryptionResult.Error + "\""); } } }
private async void EncryptButton_Click(object sender, RoutedEventArgs e) { bool RemoveButtonState = DisableAllControls(); if (String.IsNullOrEmpty(TextInputEditor.Text) && fileData == null) { RestoreAllControls(RemoveButtonState); await new ContentDialog() { Title = "Error", Content = "Choose file or paste text to decrypt!", CloseButtonText = "Okay" }.ShowAsync(); EncryptButton.IsEnabled = false; return; } string password = "******"; if (!PasswordSwitch.IsOn) { if (String.IsNullOrEmpty(CustomPasswordEntry.Text) || CustomPasswordEntry.Text.Length < 6 || CustomPasswordEntry.Text.Length > 16) { RestoreAllControls(RemoveButtonState); CustomPasswordEntry.Focus(FocusState.Programmatic); await new ContentDialog() { Title = "Error", Content = "Custom Password length should be at least 6 and at most 16", CloseButtonText = "Okay" }.ShowAsync(); return; } password = CustomPasswordEntry.Text; } if (fileData == null) { DecryptionResult decryptionResult = null; string plainText = TextInputEditor.Text; await Task.Run(() => { decryptionResult = DecryptionService.DecryptText(plainText, password); }); if (decryptionResult.Result) { var FormatedTextSize = DecryptionService.GetFormatedSize(System.Text.Encoding.UTF8.GetByteCount(decryptionResult.DecryptedString)); var result = await new ContentDialog() { Title = "Decrypted Text", Content = decryptionResult.DecryptedString, PrimaryButtonText = "Copy decrypted text", CloseButtonText = "Do not copy" }.ShowAsync(); if (result == ContentDialogResult.Primary) { var DP = new DataPackage(); DP.SetText(decryptionResult.DecryptedString); Clipboard.SetContent(DP); } fileData = null; RestoreAllControls(false); RemoveButton_Click(null, null); TextInputEditor.Text = String.Empty; CustomPasswordEntry.Text = String.Empty; PasswordSwitch.IsOn = true; } else { await new ContentDialog() { Title = "Failed", Content = "Decryption failed. This text can not be decrypted. Error: \"" + decryptionResult.Error + "\"", CloseButtonText = "Okay" }.ShowAsync(); RestoreAllControls(RemoveButtonState); } } else { DecryptionResult decryptionResult = null; await Task.Run(async() => { decryptionResult = await DecryptionService.DecryptFile(fileData, password); }); if (decryptionResult.Result) { ActivityText.Text = "Do not close the application. Saving decrypted file."; FileSavePicker savePicker = new FileSavePicker(); var FileNameExtension = System.IO.Path.GetExtension(decryptionResult.WritePath); savePicker.FileTypeChoices.Add("Crypto App Decrypted File", new List <string>() { FileNameExtension }); savePicker.SuggestedFileName = System.IO.Path.GetFileName(decryptionResult.WritePath); var writeFile = await savePicker.PickSaveFileAsync(); if (writeFile != null) { CachedFileManager.DeferUpdates(writeFile); await FileIO.WriteBytesAsync(writeFile, decryptionResult.DecryptedContents); FileUpdateStatus status = await CachedFileManager.CompleteUpdatesAsync(writeFile); if (status == FileUpdateStatus.Complete) { await new ContentDialog() { Title = "Success", Content = "File is decrypted and saved as " + writeFile.Name, CloseButtonText = "Okay" }.ShowAsync(); } else { await new ContentDialog() { Title = "Failure", Content = "File could not be saved! ", CloseButtonText = "Okay" }.ShowAsync(); } } else { await new ContentDialog() { Title = "Cancelled", Content = "File was not saved! ", CloseButtonText = "Okay" }.ShowAsync(); } RestoreAllControls(false); fileData = null; RemoveButton_Click(null, null); TextInputEditor.Text = String.Empty; CustomPasswordEntry.Text = String.Empty; PasswordSwitch.IsOn = true; } else if (decryptionResult.Result == false && decryptionResult.Error == "Password") { await new ContentDialog() { Title = "Error", Content = "Password is wrong. Enter correct password to decrypt.", CloseButtonText = "Okay" }.ShowAsync(); RestoreAllControls(RemoveButtonState); PasswordSwitch.IsOn = false; CustomPasswordStack.Visibility = Visibility.Visible; CustomPasswordEntry.Focus(FocusState.Programmatic); return; } else { await new ContentDialog() { Title = "Failed", Content = "Decryption failed. This file can not be decrypted. Error: \"" + decryptionResult.Error + "\"", CloseButtonText = "Okay" }.ShowAsync(); RestoreAllControls(RemoveButtonState); } } }
static void Main() { Context ctx = new Context(); if (ctx.Protocol != Protocol.OpenPGP) { ctx.SetEngineInfo(Protocol.OpenPGP, null, null); } Console.WriteLine("Search Bob's and Alice's PGP keys in the default keyring.."); String[] searchpattern = new[] { "*****@*****.**", "*****@*****.**" }; IKeyStore keyring = ctx.KeyStore; // We want the key signatures! ctx.KeylistMode = KeylistMode.Signatures; // retrieve all keys that have Bob's or Alice's email address Key[] keys = keyring.GetKeyList(searchpattern, false); PgpKey bob = null, alice = null; if (keys != null && keys.Length != 0) { foreach (Key k in keys) { if (k.Uid != null) { if (bob == null && k.Uid.Email.ToLower().Equals("*****@*****.**")) { bob = (PgpKey)k; } if (alice == null && k.Uid.Email.ToLower().Equals("*****@*****.**")) { alice = (PgpKey)k; } } else { throw new InvalidKeyException(); } } } if (bob == null || alice == null) { Console.WriteLine("Cannot find Bob's or Alice's PGP key in your keyring."); Console.WriteLine("You may want to create the PGP keys by using the appropriate\n" + "sample in the Samples/ directory."); return; } // Create a sample string StringBuilder randomtext = new StringBuilder(); for (int i = 0; i < 80 * 6; i++) { randomtext.Append((char)(34 + i % 221)); } string origintxt = new string('+', 508) + " Die Gedanken sind frei " + new string('+', 508) + randomtext; // we want our string UTF8 encoded. UTF8Encoding utf8 = new UTF8Encoding(); // Write sample string to plain.txt File.WriteAllText("plain.txt", origintxt, utf8); /////// ENCRYPT AND SIGN DATA /////// Console.Write("Encrypt data for Bob and sign it with Alice's PGP key.. "); GpgmeData plain = new GpgmeFileData("plain.txt"); GpgmeData cipher = new GpgmeFileData("cipher.asc"); // we want or PGP encrypted/signed data RADIX/BASE64 encoded. ctx.Armor = true; /* Set the password callback - needed if the user doesn't run * gpg-agent or any other password / pin-entry software. */ ctx.SetPassphraseFunction(MyPassphraseCallback); // Set Alice's PGP key as signer ctx.Signers.Clear(); ctx.Signers.Add(alice); EncryptionResult encrst = ctx.EncryptAndSign( new Key[] { bob }, EncryptFlags.AlwaysTrust, plain, cipher); Console.WriteLine("done."); // print out invalid signature keys if (encrst.InvalidRecipients != null) { foreach (InvalidKey key in encrst.InvalidRecipients) { Console.WriteLine("Invalid key: {0} ({1})", key.Fingerprint, key.Reason); } } plain.Close(); cipher.Close(); /////// DECRYPT AND VERIFY DATA /////// Console.Write("Decrypt and verify data.. "); cipher = new GpgmeFileData("cipher.asc"); plain = new GpgmeMemoryData(); CombinedResult comrst = ctx.DecryptAndVerify( cipher, // source buffer plain); // destination buffer Console.WriteLine("Done. Filename: \"{0}\" Recipients:", comrst.DecryptionResult.FileName); /* print out all recipients key ids (a PGP package can be * encrypted to various recipients). */ DecryptionResult decrst = comrst.DecryptionResult; if (decrst.Recipients != null) { foreach (Recipient recp in decrst.Recipients) { Console.WriteLine("\tKey id {0} with {1} algorithm", recp.KeyId, Gpgme.GetPubkeyAlgoName(recp.KeyAlgorithm)); } } else { Console.WriteLine("\tNone"); } // print out signature information VerificationResult verrst = comrst.VerificationResult; if (verrst.Signature != null) { foreach (Signature sig in verrst.Signature) { Console.WriteLine("Verification result (signature): " + "\n\tFingerprint: {0}" + "\n\tHash algorithm: {1}" + "\n\tKey algorithm: {2}" + "\n\tTimestamp: {3}" + "\n\tSummary: {4}" + "\n\tValidity: {5}", sig.Fingerprint, Gpgme.GetHashAlgoName(sig.HashAlgorithm), Gpgme.GetPubkeyAlgoName(sig.PubkeyAlgorithm), sig.Timestamp, sig.Summary, sig.Validity); } } }
internal CombinedResult(DecryptionResult decrst, VerificationResult verrst) { DecryptionResult = decrst; VerificationResult = verrst; }
public DecryptionFailedException(DecryptionResult rst) { DecryptionResult = rst; }