/// <summary> /// Initializes a new instance of the <see cref="PgpDecrypter" /> class. /// </summary> /// <param name="secretKeyRingBundle">The secret key ring.</param> /// <param name="passPhraseChars">The pass phrase chars.</param> /// <exception cref="System.ArgumentNullException">secretKeyRingBundle</exception> public PgpDecrypter(PgpSecretKeyRingBundle secretKeyRingBundle, char[] passPhraseChars) { if (secretKeyRingBundle == null) throw new ArgumentNullException("secretKeyRingBundle"); if (passPhraseChars == null) throw new ArgumentNullException("passPhraseChars"); _secretKeyRingBundle = secretKeyRingBundle; _passPhraseChars = passPhraseChars; }
//private static string Password = ConfigurationManager.AppSettings["Password"]; //public static string PublicKey = ConfigurationManager.AppSettings["PublicKey"]; //public static string PublicKeyPath = IoHelper.BasePath + @"\" + PublicKey; //// note: this should be changed if the private key is not located in the current executables path //private static string PrivateKeyOnly = ConfigurationManager.AppSettings["PrivateKeyOnly"]; //private static string PrivateKeyOnlyPath = IoHelper.BasePath + @"\" + PrivateKeyOnly; // The majority of the functionality encrypting/decrypting came from this answer: http://stackoverflow.com/a/10210465 private static PgpPrivateKey FindSecretKey(PgpSecretKeyRingBundle pgpSec, long keyId, char[] pass) { PgpSecretKey pgpSecKey = pgpSec.GetSecretKey(keyId); if (pgpSecKey == null) { return null; } return pgpSecKey.ExtractPrivateKey(pass); }
/// <summary> /// Return the first key we can use to encrypt. /// Note: A file can contain multiple keys (stored in "key rings") /// </summary> private PgpSecretKey GetFirstSecretKey(PgpSecretKeyRingBundle secretKeyRingBundle) { foreach (PgpSecretKeyRing kRing in secretKeyRingBundle.GetKeyRings()) { PgpSecretKey key = kRing.GetSecretKeys() .Cast<PgpSecretKey>() .Where(k => k.IsSigningKey) .FirstOrDefault(); if (key != null) return key; } return null; }
private PgpSecretKey ReadSecretKey(string privateKeyPath) { using (Stream keyIn = File.OpenRead(privateKeyPath)) { using (Stream inputStream = PgpUtilities.GetDecoderStream(keyIn)) { PgpSecretKeyRingBundle secretKeyRingBundle = new PgpSecretKeyRingBundle(inputStream); PgpSecretKey foundKey = GetFirstSecretKey(secretKeyRingBundle); if (foundKey != null) return foundKey; } } throw new ArgumentException("Can't find signing key in key ring."); }
public static PgpSecretKeyRingBundle RemoveSecretKeyRing(PgpSecretKeyRingBundle bundle, PgpSecretKeyRing secretKeyRing) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) long keyId = secretKeyRing.GetPublicKey().KeyId; if (!bundle.secretRings.Contains((object)keyId)) { throw new ArgumentException("Collection does not contain a key with a keyId for the passed in ring."); } IDictionary val = Platform.CreateHashtable(bundle.secretRings); global::System.Collections.IList list = Platform.CreateArrayList((global::System.Collections.ICollection)bundle.order); val.Remove((object)keyId); list.Remove((object)keyId); return(new PgpSecretKeyRingBundle(val, list)); }
/// <summary> /// Return a new bundle containing the contents of the passed in bundle with /// the passed in secret key ring removed. /// </summary> /// <param name="bundle">The <c>PgpSecretKeyRingBundle</c> the key ring is to be removed from.</param> /// <param name="secretKeyRing">The key ring to be removed.</param> /// <returns>A new <c>PgpSecretKeyRingBundle</c> not containing the passed in key ring.</returns> /// <exception cref="ArgumentException">If the keyId for the passed in key ring is not present.</exception> public static PgpSecretKeyRingBundle RemoveSecretKeyRing(PgpSecretKeyRingBundle bundle, PgpSecretKeyRing secretKeyRing) { var key = secretKeyRing.GetPublicKey().KeyId; if (!bundle._secretRings.Contains(key)) { throw new ArgumentException("Collection does not contain a key with a keyId for the passed in ring."); } var newSecretRings = Platform.CreateHashtable(bundle._secretRings); var newOrder = Platform.CreateArrayList(bundle._order); newSecretRings.Remove(key); newOrder.Remove(key); return(new PgpSecretKeyRingBundle(newSecretRings, newOrder)); }
private static PgpSecretKey ReadSecretKey(Stream inputStream) { var decodedInputStream = PgpUtilities.GetDecoderStream(inputStream); var secretKeyRingBundle = new PgpSecretKeyRingBundle(decodedInputStream); // we just loop through the collection till we find a key suitable for encryption, in the real // world you would probably want to be a bit smarter about this. foreach (PgpSecretKeyRing keyRing in secretKeyRingBundle.GetKeyRings()) { foreach (PgpSecretKey key in keyRing.GetSecretKeys()) { if (key.IsSigningKey) return key; } } throw new ArgumentException("Can't find signing key in key ring."); }
/// <summary> /// Return a new bundle containing the contents of the passed in bundle and /// the passed in secret key ring. /// </summary> /// <param name="bundle">The <c>PgpSecretKeyRingBundle</c> the key ring is to be added to.</param> /// <param name="secretKeyRing">The key ring to be added.</param> /// <returns>A new <c>PgpSecretKeyRingBundle</c> merging the current one with the passed in key ring.</returns> /// <exception cref="ArgumentException">If the keyId for the passed in key ring is already present.</exception> public static PgpSecretKeyRingBundle AddSecretKeyRing( PgpSecretKeyRingBundle bundle, PgpSecretKeyRing secretKeyRing) { long key = secretKeyRing.GetPublicKey().KeyId; if (bundle.secretRings.Contains(key)) { throw new ArgumentException("Collection already contains a key with a keyId for the passed in ring."); } IDictionary newSecretRings = Platform.CreateHashtable(bundle.secretRings); IList newOrder = Platform.CreateArrayList(bundle.order); newSecretRings[key] = secretKeyRing; newOrder.Add(key); return(new PgpSecretKeyRingBundle(newSecretRings, newOrder)); }
/// <summary> /// Return a new bundle containing the contents of the passed in bundle with /// the passed in secret key ring removed. /// </summary> /// <param name="bundle">The <c>PgpSecretKeyRingBundle</c> the key ring is to be removed from.</param> /// <param name="secretKeyRing">The key ring to be removed.</param> /// <returns>A new <c>PgpSecretKeyRingBundle</c> not containing the passed in key ring.</returns> /// <exception cref="ArgumentException">If the keyId for the passed in key ring is not present.</exception> public static PgpSecretKeyRingBundle RemoveSecretKeyRing( PgpSecretKeyRingBundle bundle, PgpSecretKeyRing secretKeyRing) { long key = secretKeyRing.GetPublicKey().KeyId; if (!bundle.secretRings.Contains(key)) { throw new ArgumentException("Collection does not contain a key with a keyId for the passed in ring."); } IDictionary newSecretRings = new Hashtable(bundle.secretRings); ArrayList newOrder = new ArrayList(bundle.order); newSecretRings.Remove(key); newOrder.Remove(key); return(new PgpSecretKeyRingBundle(newSecretRings, newOrder)); }
private static Tuple <PgpPublicKeyEncryptedData, PgpObjectFactory> Decrypt(PgpEncryptedDataList pgpEncryptedDatalist, Stream privateKeyStream, string praKeyPwd) { var pkstream = Org.BouncyCastle.Bcpg.OpenPgp.PgpUtilities.GetDecoderStream(privateKeyStream); var bundle = new Org.BouncyCastle.Bcpg.OpenPgp.PgpSecretKeyRingBundle(pkstream); foreach (PgpPublicKeyEncryptedData encryptedData in pgpEncryptedDatalist.GetEncryptedDataObjects()) { var privateKey = bundle.GetSecretKey(encryptedData.KeyId)?.ExtractPrivateKey(praKeyPwd.ToCharArray()); if (privateKey == null) { continue; } using (var tmp = encryptedData.GetDataStream(privateKey)) { return(Tuple.Create(encryptedData, new PgpObjectFactory(tmp))); } } throw new ArgumentException("未能正常读取到加密文件内容,请检查文件及密钥"); }
public static bool ValidatePassPhrase(byte[] privateKey, string passPhrase) { using (MemoryStream privateKeyStream = new MemoryStream(privateKey)) { PgpSecretKeyRingBundle pgpKeyRing = new PgpSecretKeyRingBundle(PgpUtilities.GetDecoderStream(privateKeyStream)); var items = pgpKeyRing.GetKeyRings(); foreach (var item in items) { try { var i = (PgpSecretKeyRing) item; var key = i.GetSecretKey().ExtractPrivateKey(passPhrase.ToCharArray()); return true; } catch (Exception ex){ Insights.Report(ex); return false; } } } return true; }
/// <summary> /// Return a new bundle containing the contents of the passed in bundle and /// the passed in secret key ring. /// </summary> /// <param name="bundle">The <c>PgpSecretKeyRingBundle</c> the key ring is to be added to.</param> /// <param name="secretKeyRing">The key ring to be added.</param> /// <returns>A new <c>PgpSecretKeyRingBundle</c> merging the current one with the passed in key ring.</returns> /// <exception cref="ArgumentException">If the keyId for the passed in key ring is already present.</exception> public static PgpSecretKeyRingBundle AddSecretKeyRing( PgpSecretKeyRingBundle bundle, PgpSecretKeyRing secretKeyRing) { long key = secretKeyRing.GetPublicKey().KeyId; if (bundle.secretRings.Contains(key)) { throw new ArgumentException("Collection already contains a key with a keyId for the passed in ring."); } IDictionary newSecretRings = new Hashtable(bundle.secretRings); ArrayList newOrder = new ArrayList(bundle.order); newSecretRings[key] = secretKeyRing; newOrder.Add(key); return new PgpSecretKeyRingBundle(newSecretRings, newOrder); }
public PgpSecretKey GetSecretKey(long Id) { using (var inputStream = File.OpenRead(Context.PrivateKeyRingFile)) { using (var decoderStream = PgpUtilities.GetDecoderStream(inputStream)) { var pgpPub = new PgpSecretKeyRingBundle(decoderStream); foreach (PgpSecretKeyRing kRing in pgpPub.GetKeyRings()) { foreach (PgpSecretKey k in kRing.GetSecretKeys()) { if (k.KeyId == Id) return k; } } return null; } } }
public static Stream PgpDecrypt(this Stream encryptedData, string armoredPrivateKey, string privateKeyPassword, Encoding armorEncoding = null) { var stream = PgpUtilities.GetDecoderStream(encryptedData); var layeredStreams = new List<Stream> { stream }; //this is to clean up/ dispose of any layered streams. var dataObjectFactory = new PgpObjectFactory(stream); var dataObject = dataObjectFactory.NextPgpObject(); Dictionary<long, PgpSecretKey> secretKeys; using (var privateKeyStream = armoredPrivateKey.Streamify(armorEncoding ?? Encoding.UTF8)) using (var decoderStream = PgpUtilities.GetDecoderStream(privateKeyStream)) { secretKeys = new PgpSecretKeyRingBundle(decoderStream) .GetKeyRings() .OfType<PgpSecretKeyRing>() .SelectMany(x => x.GetSecretKeys().OfType<PgpSecretKey>()) .ToDictionary(key => key.KeyId, value => value); if (!secretKeys.Any()) throw new ArgumentException("No secret keys found."); } while (!(dataObject is PgpLiteralData) && dataObject != null) { try { var compressedData = dataObject as PgpCompressedData; var listedData = dataObject as PgpEncryptedDataList; //strip away the compression stream if (compressedData != null) { stream = compressedData.GetDataStream(); layeredStreams.Add(stream); dataObjectFactory = new PgpObjectFactory(stream); } //strip the PgpEncryptedDataList if (listedData != null) { var encryptedDataList = listedData. GetEncryptedDataObjects() .OfType<PgpPublicKeyEncryptedData>() .First(); var decryptionKey = secretKeys[encryptedDataList.KeyId] .ExtractPrivateKey(privateKeyPassword.ToCharArray()); stream = encryptedDataList.GetDataStream(decryptionKey); layeredStreams.Add(stream); dataObjectFactory = new PgpObjectFactory(stream); } dataObject = dataObjectFactory.NextPgpObject(); } catch (Exception ex) { //Log exception here. throw new PgpException("Failed to strip encapsulating streams.", ex); } } foreach (var layeredStream in layeredStreams) { layeredStream.Close(); layeredStream.Dispose(); } if (dataObject == null) return null; return (dataObject as PgpLiteralData).GetInputStream(); }
/** * decrypt the passed in message stream */ private static void DecryptFile( Stream inputStream, Stream keyIn, char[] passwd, string pathToDecryptedFile) //DC { try { inputStream = PgpUtilities.GetDecoderStream(inputStream); try { PgpObjectFactory pgpF = new PgpObjectFactory(inputStream); PgpEncryptedDataList enc; PgpObject o = pgpF.NextPgpObject(); // // the first object might be a PGP marker packet. // if (o is PgpEncryptedDataList) { enc = (PgpEncryptedDataList)o; } else { enc = (PgpEncryptedDataList)pgpF.NextPgpObject(); } // // find the secret key // PgpPrivateKey sKey = null; PgpPublicKeyEncryptedData pbe = null; PgpSecretKeyRingBundle pgpSec = new PgpSecretKeyRingBundle( PgpUtilities.GetDecoderStream(keyIn)); foreach (PgpPublicKeyEncryptedData pked in enc.GetEncryptedDataObjects()) { sKey = OpenPgp_HelperMethods.FindSecretKey(pgpSec, pked.KeyId, passwd); if (sKey != null) { pbe = pked; break; } } if (sKey == null) { throw new ArgumentException("secret key for message not found."); } Stream clear = pbe.GetDataStream(sKey); PgpObjectFactory plainFact = new PgpObjectFactory(clear); PgpObject message = plainFact.NextPgpObject(); PgpObjectFactory pgpFact = null; if (message is PgpCompressedData) { PgpCompressedData cData = (PgpCompressedData)message; pgpFact = new PgpObjectFactory(cData.GetDataStream()); message = pgpFact.NextPgpObject(); } if (message is PgpOnePassSignatureList) // DC { // DC message = pgpFact.NextPgpObject(); // DC } // DC if (message is PgpLiteralData) { PgpLiteralData ld = (PgpLiteralData)message; Stream fOut = File.Create(pathToDecryptedFile); //DC (modified to use the name provided in pathToDecryptedFile Stream unc = ld.GetInputStream(); Streams.PipeAll(unc, fOut); fOut.Close(); } else if (message is PgpOnePassSignatureList) { "[API_OpenPgp][DecryptFile] encrypted message contains a signed message - not literal data.".error(); return ; } else { "[API_OpenPgp][DecryptFile] message is not a simple encrypted file - type unknown.".error(); return; } if (pbe.IsIntegrityProtected()) { if (!pbe.Verify()) { "[API_OpenPgp][DecryptFile] message failed integrity check".error(); } else { "[API_OpenPgp][DecryptFile] message integrity check passed".debug(); } } else { "[API_OpenPgp][DecryptFile] no message integrity check".error(); } } catch (PgpException e) { e.log("[API_OpenPgp] in DecryptFile: " + e.StackTrace ); /*Console.Error.WriteLine(e); Exception underlyingException = e.InnerException; if (underlyingException != null) { Console.Error.WriteLine(underlyingException.Message); Console.Error.WriteLine(underlyingException.StackTrace); }*/ } } catch (Exception ex) { ex.log("[API_OpenPgp] in DecryptFile : " + ex.StackTrace ); } }
public static PgpSecretKey ReadSecretKey( Stream inputStream) { inputStream = PgpUtilities.GetDecoderStream(inputStream); PgpSecretKeyRingBundle pgpSec = new PgpSecretKeyRingBundle(inputStream); // // we just loop through the collection till we find a key suitable for encryption, in the real // world you would probably want to be a bit smarter about this. // foreach (PgpSecretKeyRing kRing in pgpSec.GetKeyRings()) { foreach (PgpSecretKey k in kRing.GetSecretKeys()) { if (k.IsSigningKey) { return k; } } } throw new ArgumentException("Can't find signing key in key ring."); }
public PgpSecretKey GetSecretKeyForSigning(string email) { using (var inputStream = File.OpenRead(Context.PrivateKeyRingFile)) { using (var decoderStream = PgpUtilities.GetDecoderStream(inputStream)) { var pgpPub = new PgpSecretKeyRingBundle(decoderStream); var emailSearch = "<" + email.ToLower().Trim() + ">"; foreach (PgpSecretKeyRing kRing in pgpPub.GetKeyRings()) { foreach (PgpSecretKey k in kRing.GetSecretKeys()) { if (!IsSigningKey(k.PublicKey)) continue; if (!k.IsMasterKey) { foreach (PgpSignature sig in k.PublicKey.GetSignaturesOfType(24)) { var pubKey = this.GetPublicKey(sig.KeyId); if (!pubKey.IsMasterKey) continue; foreach (string id in pubKey.GetUserIds()) { if (id.ToLower().IndexOf(emailSearch) > -1) return k; } } } foreach (string id in k.PublicKey.GetUserIds()) { if (id.ToLower().IndexOf(emailSearch) > -1) return k; } } } return null; } } }
public PgpSecretKey LoadSecKey(string path) { using (Stream keyIn = File.OpenRead(path)) { Stream decStream = PgpUtilities.GetDecoderStream (keyIn); PgpSecretKeyRingBundle pgpSec = new PgpSecretKeyRingBundle (decStream); foreach (PgpSecretKeyRing keyRing in pgpSec.GetKeyRings()) { foreach (PgpSecretKey key in keyRing.GetSecretKeys()) { if (key.IsSigningKey) { return key; } } } throw new ArgumentException ("Can't find signing key in key ring."); } }
public string[] GetSecretKeyUserIds() { using (var inputStream = File.OpenRead(Context.PrivateKeyRingFile)) { using (var decoderStream = PgpUtilities.GetDecoderStream(inputStream)) { var pgpPub = new PgpSecretKeyRingBundle(decoderStream); var keyUserIds = new List<string>(); foreach (PgpSecretKeyRing kRing in pgpPub.GetKeyRings()) { foreach (PgpSecretKey k in kRing.GetSecretKeys()) { if (!k.IsMasterKey) { foreach (PgpSignature sig in k.PublicKey.GetSignaturesOfType(24)) { var pubKey = this.GetPublicKey(sig.KeyId); if (!pubKey.IsMasterKey) continue; foreach (string id in pubKey.GetUserIds()) { if (!keyUserIds.Contains(id)) keyUserIds.Add(id); } } } foreach (string id in k.PublicKey.GetUserIds()) { if(!keyUserIds.Contains(id)) keyUserIds.Add(id); } } } return keyUserIds.ToArray(); } } }
/// <summary> /// Decrypt a PGP message (i.e. "-----BEGIN PGP MESSAGE----- ... -----END PGP MESSAGE-----") /// using the supplied private key. /// </summary> /// <param name="armoredCipher">PGP message to decrypt</param> /// <param name="armoredPrivateKey">PGP private key</param> /// <param name="keyPassword">PGP private key password or null if none</param> /// <returns>decrypted plain text</returns> public static string PGPDecrypt(string armoredCipher, string armoredPrivateKey, string keyPassword) { // decode the private key PgpPrivateKey privateKey = null; using (MemoryStream ms = new MemoryStream(Encoding.ASCII.GetBytes(armoredPrivateKey))) { using (Stream dis = PgpUtilities.GetDecoderStream(ms)) { PgpSecretKeyRingBundle bundle = new PgpSecretKeyRingBundle(dis); foreach (PgpSecretKeyRing keyring in bundle.GetKeyRings()) { foreach (PgpSecretKey key in keyring.GetSecretKeys()) { privateKey = key.ExtractPrivateKey(keyPassword != null ? keyPassword.ToCharArray() : null); break; } } } } // decrypt armored block using our private key byte[] cipher = Encoding.ASCII.GetBytes(armoredCipher); using (MemoryStream decryptedStream = new MemoryStream()) { using (MemoryStream inputStream = new MemoryStream(cipher)) { using (ArmoredInputStream ais = new ArmoredInputStream(inputStream)) { PgpObject message = new PgpObjectFactory(ais).NextPgpObject(); if (message is PgpEncryptedDataList) { foreach (PgpPublicKeyEncryptedData pked in ((PgpEncryptedDataList)message).GetEncryptedDataObjects()) { message = new PgpObjectFactory(pked.GetDataStream(privateKey)).NextPgpObject(); } } if (message is PgpCompressedData) { message = new PgpObjectFactory(((PgpCompressedData)message).GetDataStream()).NextPgpObject(); } if (message is PgpLiteralData) { byte[] buffer = new byte[4096]; using (Stream stream = ((PgpLiteralData)message).GetInputStream()) { int read; while ((read = stream.Read(buffer, 0, 4096)) > 0) { decryptedStream.Write(buffer, 0, read); } } } return Encoding.UTF8.GetString(decryptedStream.ToArray()); } } } }
private static PgpPrivateKey FindSecretKey( Stream keyIn, long keyId, char[] pass) { PgpSecretKeyRingBundle pgpSec = new PgpSecretKeyRingBundle( PgpUtilities.GetDecoderStream(keyIn)); PgpSecretKey pgpSecKey = pgpSec.GetSecretKey(keyId); if (pgpSecKey == null) { return null; } return pgpSecKey.ExtractPrivateKey(pass); }
/// <summary> /// Return the first key we can use to encrypt. /// Note: A file can contain multiple keys (stored in "key rings") /// </summary> private PgpSecretKey getFirstSecretKey(PgpSecretKeyRingBundle secretKeyRingBundle) { foreach (PgpSecretKeyRing kRing in secretKeyRingBundle.GetKeyRings()) { // Note: You may need to use something other than the first key // in your key ring. Keep that in mind. // ex: .Where(k => !k.IsSigningKey) PgpSecretKey key = kRing.GetSecretKeys() .Cast<PgpSecretKey>() //.Where(k => k.IsSigningKey) .Where(k => !k.IsSigningKey) .FirstOrDefault(); if (key != null) { return key; } } return null; }
/// <summary> /// Imports secret pgp keys from the specified stream. /// </summary> /// <remarks> /// Imports secret pgp keys from the specified stream. /// </remarks> /// <param name="rawData">The raw key data.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="rawData"/> is <c>null</c>. /// </exception> /// <exception cref="System.IO.IOException"> /// <para>An error occurred while parsing the raw key-ring data</para> /// <para>-or-</para> /// <para>An error occured while saving the public key-ring bundle.</para> /// </exception> public virtual void ImportSecretKeys (Stream rawData) { if (rawData == null) throw new ArgumentNullException ("rawData"); using (var armored = new ArmoredInputStream (rawData)) { var imported = new PgpSecretKeyRingBundle (armored); if (imported.Count == 0) return; int secretKeysAdded = 0; foreach (PgpSecretKeyRing secring in imported.GetKeyRings ()) { if (!SecretKeyRingBundle.Contains (secring.GetSecretKey ().KeyId)) { SecretKeyRingBundle = PgpSecretKeyRingBundle.AddSecretKeyRing (SecretKeyRingBundle, secring); secretKeysAdded++; } } if (secretKeysAdded > 0) SaveSecretKeyRingBundle (); } }
/// <summary> /// Initializes a new instance of the <see cref="MimeKit.Cryptography.OpenPgpContext"/> class. /// </summary> /// <remarks> /// Creates a new <see cref="OpenPgpContext"/> using the specified public and private keyring paths. /// </remarks> /// <param name="pubring">The public keyring file path.</param> /// <param name="secring">The secret keyring file path.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="pubring"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="secring"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.IO.IOException"> /// An error occurred while reading one of the keyring files. /// </exception> /// <exception cref="Org.BouncyCastle.Bcpg.OpenPgp.PgpException"> /// An error occurred while parsing one of the keyring files. /// </exception> protected OpenPgpContext (string pubring, string secring) { if (pubring == null) throw new ArgumentNullException ("pubring"); if (secring == null) throw new ArgumentNullException ("secring"); PublicKeyRingPath = pubring; SecretKeyRingPath = secring; if (File.Exists (pubring)) { using (var file = File.OpenRead (pubring)) { PublicKeyRingBundle = new PgpPublicKeyRingBundle (file); } } else { PublicKeyRingBundle = new PgpPublicKeyRingBundle (new byte[0]); } if (File.Exists (secring)) { using (var file = File.OpenRead (secring)) { SecretKeyRingBundle = new PgpSecretKeyRingBundle (file); } } else { SecretKeyRingBundle = new PgpSecretKeyRingBundle (new byte[0]); } }
public static void SignAndEncryptFile(string actualFileName, string embeddedFileName, Stream privateKeyStream, string passPhrase, Stream publicKeyStream, bool armor, bool withIntegrityCheck, Stream outputStream) { const int BUFFER_SIZE = 1 << 16; // should always be power of 2 if (armor) outputStream = new ArmoredOutputStream(outputStream); PgpPublicKey pubKey = ReadPublicKey(publicKeyStream); // Init encrypted data generator PgpEncryptedDataGenerator encryptedDataGenerator = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Cast5, withIntegrityCheck, new SecureRandom()); encryptedDataGenerator.AddMethod(pubKey); Stream encryptedOut = encryptedDataGenerator.Open(outputStream, new byte[BUFFER_SIZE]); // Init compression PgpCompressedDataGenerator compressedDataGenerator = new PgpCompressedDataGenerator(CompressionAlgorithmTag.Zip); Stream compressedOut = compressedDataGenerator.Open(encryptedOut); // Init signature PgpSecretKeyRingBundle pgpSecBundle = new PgpSecretKeyRingBundle(PgpUtilities.GetDecoderStream(privateKeyStream)); var pgpSecKey = ReadSecretKey(pgpSecBundle); if (pgpSecKey == null) throw new ArgumentException(pubKey.KeyId.ToString("X") + " could not be found in specified key ring bundle.", "keyId"); PgpPrivateKey pgpPrivKey = pgpSecKey.ExtractPrivateKey(passPhrase.ToCharArray()); PgpSignatureGenerator signatureGenerator = new PgpSignatureGenerator(pgpSecKey.PublicKey.Algorithm, HashAlgorithmTag.Sha1); signatureGenerator.InitSign(PgpSignature.BinaryDocument, pgpPrivKey); var userIds = pgpSecKey.PublicKey.GetUserIds(); string userId = null; foreach (string value in userIds) { // Just the first one! userId = value; break; } if (string.IsNullOrEmpty(userId)) { throw new ArgumentException(string.Format("Can't find userId in signing key. KeyId '{0}'.", pubKey.KeyId.ToString("X"))); } PgpSignatureSubpacketGenerator spGen = new PgpSignatureSubpacketGenerator(); spGen.SetSignerUserId(false, userId); signatureGenerator.SetHashedSubpackets(spGen.Generate()); signatureGenerator.GenerateOnePassVersion(false).Encode(compressedOut); // Create the Literal Data generator output stream PgpLiteralDataGenerator literalDataGenerator = new PgpLiteralDataGenerator(); // NOTE: Commented this out because it uses FileInfo to get stats on files and won't work properly FileInfo embeddedFile = new FileInfo(embeddedFileName); FileInfo actualFile = new FileInfo(actualFileName); if (!actualFile.Exists) { throw new FileNotFoundException(actualFile.FullName); } // TODO: Use lastwritetime from source file Stream literalOut = literalDataGenerator.Open(compressedOut, PgpLiteralData.Binary, embeddedFile.Name, actualFile.LastWriteTime, new byte[BUFFER_SIZE]); // Open the input file FileStream inputStream = actualFile.OpenRead(); byte[] buf = new byte[BUFFER_SIZE]; int len; while ((len = inputStream.Read(buf, 0, buf.Length)) > 0) { literalOut.Write(buf, 0, len); signatureGenerator.Update(buf, 0, len); } literalOut.Close(); literalDataGenerator.Close(); signatureGenerator.Generate().Encode(compressedOut); compressedOut.Close(); compressedDataGenerator.Close(); encryptedOut.Close(); encryptedDataGenerator.Close(); inputStream.Close(); if (armor) outputStream.Close(); }
/// <summary> /// Return the first key we can use to encrypt. /// Note: A file can contain multiple keys (stored in "key rings") /// </summary> private PgpSecretKey GetFirstSecretKey(PgpSecretKeyRingBundle secretKeyRingBundle) { foreach (PgpSecretKeyRing kRing in secretKeyRingBundle.GetKeyRings()) { PgpSecretKey key = null; foreach(PgpSecretKey k in kRing.GetSecretKeys()) { /*.Cast<PgpSecretKey>() .Where(k >= k.IsSigningKey) .FirstOrDefault();*/ if (k.IsSigningKey) { key = k; break; } } if (key != null) return key; } return null; }
public void VerifySignature(Stream input, string outputpath) { input = PgpUtilities.GetDecoderStream(input); PgpObjectFactory pgpObjF = new PgpObjectFactory(input); //IList collection = pgpObjF.AllPgpObjects(); PgpEncryptedDataList enc = (PgpEncryptedDataList) pgpObjF.NextPgpObject(); PgpPrivateKey sKey = null; PgpPublicKeyEncryptedData pbe = null; PgpSecretKeyRingBundle pgpSec = new PgpSecretKeyRingBundle(PgpUtilities. GetDecoderStream(File.OpenRead(m_encryptionKeys.PrivateKeyPathd))); foreach (PgpPublicKeyEncryptedData pked in enc.GetEncryptedDataObjects()) { sKey = FindSecretKey(pgpSec, pked.KeyId, m_encryptionKeys.PassPhrase.ToCharArray()); if (sKey != null) { pbe = pked; break; } } if (sKey == null) { throw new ArgumentException("secret key for message not found."); } Stream clear = pbe.GetDataStream(sKey); PgpObjectFactory plainFact = new PgpObjectFactory(clear); PgpCompressedData cData = (PgpCompressedData)plainFact.NextPgpObject(); PgpObjectFactory pgpFact = new PgpObjectFactory(cData.GetDataStream()); PgpObject message = pgpFact.NextPgpObject(); if (message is PgpOnePassSignatureList) { PgpOnePassSignatureList p1 = (PgpOnePassSignatureList)message; PgpOnePassSignature ops = p1[0]; PgpLiteralData p2 = (PgpLiteralData)pgpFact.NextPgpObject(); Stream dIn = p2.GetInputStream(); PgpPublicKeyRingBundle pgpRing = new PgpPublicKeyRingBundle(PgpUtilities. GetDecoderStream(File.OpenRead(m_encryptionKeys.PublicKeyPathd))); PgpPublicKey key = pgpRing.GetPublicKey(ops.KeyId); Stream fos = File.Create(p2.FileName); ops.InitVerify(key); int ch; while ((ch = dIn.ReadByte()) >= 0) { ops.Update((byte)ch); fos.WriteByte((byte)ch); } fos.Close(); PgpSignatureList p3 = (PgpSignatureList)pgpFact.NextPgpObject(); PgpSignature firstSig = p3[0]; if (ops.Verify(firstSig)) { throw new PgpException("signature verified."); } else { throw new PgpException("signature verification failed."); } } }
/** * decrypt the passed in message stream */ private static void DecryptFile( Stream inputStream, Stream keyIn, char[] passwd, string defaultFileName) { inputStream = PgpUtilities.GetDecoderStream(inputStream); try { PgpObjectFactory pgpF = new PgpObjectFactory(inputStream); PgpEncryptedDataList enc; PgpObject o = pgpF.NextPgpObject(); // // the first object might be a PGP marker packet. // if (o is PgpEncryptedDataList) { enc = (PgpEncryptedDataList)o; } else { enc = (PgpEncryptedDataList)pgpF.NextPgpObject(); } // // find the secret key // PgpPrivateKey sKey = null; PgpPublicKeyEncryptedData pbe = null; PgpSecretKeyRingBundle pgpSec = new PgpSecretKeyRingBundle( PgpUtilities.GetDecoderStream(keyIn)); foreach (PgpPublicKeyEncryptedData pked in enc.GetEncryptedDataObjects()) { sKey = PgpExampleUtilities.FindSecretKey(pgpSec, pked.KeyId, passwd); if (sKey != null) { pbe = pked; break; } } if (sKey == null) { throw new ArgumentException("secret key for message not found."); } Stream clear = pbe.GetDataStream(sKey); PgpObjectFactory plainFact = new PgpObjectFactory(clear); PgpCompressedData cData = (PgpCompressedData) plainFact.NextPgpObject(); PgpObjectFactory pgpFact = new PgpObjectFactory(cData.GetDataStream()); PgpObject message = pgpFact.NextPgpObject(); if (message is PgpLiteralData) { PgpLiteralData ld = (PgpLiteralData)message; string outFileName = ld.FileName; if (outFileName.Length == 0) { outFileName = defaultFileName; } Stream fOut = File.Create(outFileName); Stream unc = ld.GetInputStream(); Streams.PipeAll(unc, fOut); fOut.Close(); } else if (message is PgpOnePassSignatureList) { throw new PgpException("encrypted message contains a signed message - not literal data."); } else { throw new PgpException("message is not a simple encrypted file - type unknown."); } if (pbe.IsIntegrityProtected()) { if (!pbe.Verify()) { Console.Error.WriteLine("message failed integrity check"); } else { Console.Error.WriteLine("message integrity check passed"); } } else { Console.Error.WriteLine("no message integrity check"); } } catch (PgpException e) { Console.Error.WriteLine(e); Exception underlyingException = e.InnerException; if (underlyingException != null) { Console.Error.WriteLine(underlyingException.Message); Console.Error.WriteLine(underlyingException.StackTrace); } } }
/// <summary> /// Return a new bundle containing the contents of the passed in bundle with /// the passed in secret key ring removed. /// </summary> /// <param name="bundle">The <c>PgpSecretKeyRingBundle</c> the key ring is to be removed from.</param> /// <param name="secretKeyRing">The key ring to be removed.</param> /// <returns>A new <c>PgpSecretKeyRingBundle</c> not containing the passed in key ring.</returns> /// <exception cref="ArgumentException">If the keyId for the passed in key ring is not present.</exception> public static PgpSecretKeyRingBundle RemoveSecretKeyRing( PgpSecretKeyRingBundle bundle, PgpSecretKeyRing secretKeyRing) { long key = secretKeyRing.GetPublicKey().KeyId; if (!bundle.secretRings.Contains(key)) { throw new ArgumentException("Collection does not contain a key with a keyId for the passed in ring."); } IDictionary newSecretRings = Platform.CreateHashtable(bundle.secretRings); IList newOrder = Platform.CreateArrayList(bundle.order); newSecretRings.Remove(key); newOrder.Remove(key); return new PgpSecretKeyRingBundle(newSecretRings, newOrder); }
/* * decrypt a given stream. */ public static void Decrypt(Stream inputStream, Stream privateKeyStream, string passPhrase, string outputFile) { try { PgpObjectFactory pgpF = null; PgpEncryptedDataList enc = null; PgpObject o = null; PgpPrivateKey sKey = null; PgpPublicKeyEncryptedData pbe = null; PgpSecretKeyRingBundle pgpSec = null; pgpF = new PgpObjectFactory(PgpUtilities.GetDecoderStream(inputStream)); // find secret key pgpSec = new PgpSecretKeyRingBundle(PgpUtilities.GetDecoderStream(privateKeyStream)); if (pgpF != null) o = pgpF.NextPgpObject(); // the first object might be a PGP marker packet. if (o is PgpEncryptedDataList) enc = (PgpEncryptedDataList)o; else enc = (PgpEncryptedDataList)pgpF.NextPgpObject(); // decrypt foreach (PgpPublicKeyEncryptedData pked in enc.GetEncryptedDataObjects()) { sKey = FindSecretKey(pgpSec, pked.KeyId, passPhrase.ToCharArray()); if (sKey != null) { pbe = pked; break; } } if (sKey == null) throw new ArgumentException("Secret key for message not found."); PgpObjectFactory plainFact = null; using (Stream clear = pbe.GetDataStream(sKey)) { plainFact = new PgpObjectFactory(clear); } PgpObject message = plainFact.NextPgpObject(); if (message is PgpCompressedData) { PgpCompressedData cData = (PgpCompressedData)message; PgpObjectFactory of = null; using (Stream compDataIn = cData.GetDataStream()) { of = new PgpObjectFactory(compDataIn); } message = of.NextPgpObject(); if (message is PgpOnePassSignatureList) { message = of.NextPgpObject(); PgpLiteralData Ld = null; Ld = (PgpLiteralData)message; using (Stream output = File.Create(outputFile)) { Stream unc = Ld.GetInputStream(); Streams.PipeAll(unc, output); } } else { PgpLiteralData Ld = null; Ld = (PgpLiteralData)message; using (Stream output = File.Create(outputFile)) { Stream unc = Ld.GetInputStream(); Streams.PipeAll(unc, output); } } } else if (message is PgpLiteralData) { PgpLiteralData ld = (PgpLiteralData)message; string outFileName = ld.FileName; using (Stream fOut = File.Create(outputFile)) { Stream unc = ld.GetInputStream(); Streams.PipeAll(unc, fOut); } } else if (message is PgpOnePassSignatureList) throw new PgpException("Encrypted message contains a signed message - not literal data."); else throw new PgpException("Message is not a simple encrypted file - type unknown."); #region commented code //if (pbe.IsIntegrityProtected()) //{ // if (!pbe.Verify()) // msg = "message failed integrity check."; // //Console.Error.WriteLine("message failed integrity check"); // else // msg = "message integrity check passed."; // //Console.Error.WriteLine("message integrity check passed"); //} //else //{ // msg = "no message integrity check."; // //Console.Error.WriteLine("no message integrity check"); //} #endregion } catch (PgpException ex) { throw ex; } }
/// <summary> /// Initializes a new instance of the <see cref="MimeKit.Cryptography.OpenPgpContext"/> class. /// </summary> /// <remarks> /// Creates a new <see cref="OpenPgpContext"/> using the specified public and private keyring paths. /// </remarks> /// <param name="pubring">The public keyring file path.</param> /// <param name="secring">The secret keyring file path.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="pubring"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="secring"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.IO.IOException"> /// An error occurred while reading one of the keyring files. /// </exception> /// <exception cref="Org.BouncyCastle.Bcpg.OpenPgp.PgpException"> /// An error occurred while parsing one of the keyring files. /// </exception> protected OpenPgpContext (string pubring, string secring) : this () { if (pubring == null) throw new ArgumentNullException (nameof (pubring)); if (secring == null) throw new ArgumentNullException (nameof (secring)); PublicKeyRingPath = pubring; SecretKeyRingPath = secring; if (File.Exists (pubring)) { using (var file = File.Open (pubring, FileMode.Open, FileAccess.Read)) { PublicKeyRingBundle = new PgpPublicKeyRingBundle (file); } } else { PublicKeyRingBundle = new PgpPublicKeyRingBundle (new byte[0]); } if (File.Exists (secring)) { using (var file = File.Open (secring, FileMode.Open, FileAccess.Read)) { SecretKeyRingBundle = new PgpSecretKeyRingBundle (file); } } else { SecretKeyRingBundle = new PgpSecretKeyRingBundle (new byte[0]); } }
private PgpSecretKey readSecretKey(Stream privateKeyStream) { PgpSecretKeyRingBundle pgpSec; try { pgpSec = new PgpSecretKeyRingBundle(PgpUtilities.GetDecoderStream(privateKeyStream)); } catch (Exception e) { throw new Exception("Invalid private key stream, reason: " + e.Message); } var keyRings = pgpSec.GetKeyRings(); foreach( PgpSecretKeyRing keyRing in keyRings) { foreach(PgpSecretKey key in keyRing.GetSecretKeys()) { if( key.IsSigningKey ) return key; } } throw new Exception("Could not find a valid signing key"); }
/// <summary> /// Imports a secret pgp keyring bundle. /// </summary> /// <remarks> /// Imports a secret pgp keyring bundle. /// </remarks> /// <param name="bundle">The pgp keyring bundle.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="bundle"/> is <c>null</c>. /// </exception> public void Import (PgpSecretKeyRingBundle bundle) { if (bundle == null) throw new ArgumentNullException (nameof (bundle)); int secretKeysAdded = 0; foreach (PgpSecretKeyRing secring in bundle.GetKeyRings ()) { if (!SecretKeyRingBundle.Contains (secring.GetSecretKey ().KeyId)) { SecretKeyRingBundle = PgpSecretKeyRingBundle.AddSecretKeyRing (SecretKeyRingBundle, secring); secretKeysAdded++; } } if (secretKeysAdded > 0) SaveSecretKeyRingBundle (); }
public static Stream DecryptPgpData(Stream inputStream, Stream privateKeyStream, string privateKeyPassPhrase) { if (inputStream == null) { throw new ArgumentNullException("inputStream"); } if (privateKeyStream == null) { throw new ArgumentNullException("privateKeyStream"); } PgpObjectFactory pgpFactory = new PgpObjectFactory(PgpUtilities.GetDecoderStream(inputStream)); // find secret key PgpSecretKeyRingBundle pgpKeyRing = new PgpSecretKeyRingBundle(PgpUtilities.GetDecoderStream(privateKeyStream)); PgpObject pgp = null; if (pgpFactory != null) { pgp = pgpFactory.NextPgpObject(); } // the first object might be a PGP marker packet. PgpEncryptedDataList encryptedData = null; if (pgp is PgpEncryptedDataList) { encryptedData = (PgpEncryptedDataList)pgp; } else { encryptedData = (PgpEncryptedDataList)pgpFactory.NextPgpObject(); } // decrypt PgpPrivateKey privateKey = null; PgpPublicKeyEncryptedData pubKeyData = null; var encryptedObjects = encryptedData.GetEncryptedDataObjects(); foreach (PgpPublicKeyEncryptedData pubKeyDataItem in encryptedData.GetEncryptedDataObjects()) { privateKey = FindSecretKey(pgpKeyRing, pubKeyDataItem.KeyId, privateKeyPassPhrase.ToCharArray()); if (privateKey != null) { pubKeyData = pubKeyDataItem; break; } } if (privateKey == null) { throw new ArgumentException("Secret key for message not found."); } PgpObjectFactory plainFact = null; using (Stream clear = pubKeyData.GetDataStream(privateKey)) { plainFact = new PgpObjectFactory(clear); } PgpObject message = plainFact.NextPgpObject(); if (message is PgpCompressedData) { PgpCompressedData compressedData = (PgpCompressedData)message; PgpObjectFactory pgpCompressedFactory = null; using (Stream compDataIn = compressedData.GetDataStream()) { pgpCompressedFactory = new PgpObjectFactory(compDataIn); } message = pgpCompressedFactory.NextPgpObject(); PgpLiteralData literalData = null; if (message is PgpOnePassSignatureList) { message = pgpCompressedFactory.NextPgpObject(); } literalData = (PgpLiteralData)message; return literalData.GetInputStream(); //using (Stream unc = literalData.GetInputStream()) //{ // StreamHelper.WriteStream(unc, ref output); //} } else if (message is PgpLiteralData) { PgpLiteralData literalData = (PgpLiteralData)message; return literalData.GetInputStream(); //using (Stream unc = literalData.GetInputStream()) //{ // StreamHelper.WriteStream(unc, ref output); //} } else if (message is PgpOnePassSignatureList) { throw new PgpException("Encrypted message contains a signed message - not literal data."); } else { throw new PgpException("Message is not a simple encrypted file - type unknown."); } //return output; }
/// <summary> /// Initializes a new instance of the <see cref="MimeKit.Cryptography.OpenPgpContext"/> class. /// </summary> /// <remarks> /// Creates a new <see cref="OpenPgpContext"/> using the specified public and private keyrings. /// </remarks> /// <param name="pubring">The public keyring.</param> /// <param name="secring">The secret keyring.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="pubring"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="secring"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.IO.IOException"> /// An error occurred while reading one of the keyring files. /// </exception> /// <exception cref="Org.BouncyCastle.Bcpg.OpenPgp.PgpException"> /// An error occurred while parsing one of the keyring files. /// </exception> protected OpenPgpContext (Stream pubring, Stream secring) : this () { if (pubring == null) throw new ArgumentNullException ("pubring"); if (secring == null) throw new ArgumentNullException ("secring"); PublicKeyRing = pubring; SecretKeyRing = secring; PublicKeyRingBundle = new PgpPublicKeyRingBundle (pubring); SecretKeyRingBundle = new PgpSecretKeyRingBundle (secring); if (pubring.CanSeek) pubring.Seek (0, SeekOrigin.Begin); if (secring.CanSeek) secring.Seek (0, SeekOrigin.Begin); }