private string signEnvelopeData(string msg) { Stream privateKeyStream = getPrivateKeyStream(_privateKey); MemoryStream result = new MemoryStream(); ArmoredOutputStream aOut = new ArmoredOutputStream(result); BcpgOutputStream bOut = null; char[] privateKeyPassword = _passPhrase.ToCharArray(); var utf8Encoding = new System.Text.UTF8Encoding(); try { PgpSecretKey sk = readSecretKey(privateKeyStream); PgpPrivateKey pk = sk.ExtractPrivateKey(privateKeyPassword); PgpSignatureGenerator sigGen = new PgpSignatureGenerator(sk.PublicKey.Algorithm,HashAlgorithmTag.Sha256); PgpSignatureSubpacketGenerator spGen = new PgpSignatureSubpacketGenerator(); var enumerator = sk.PublicKey.GetUserIds().GetEnumerator(); if(enumerator.MoveNext()) { spGen.SetSignerUserId(false, (string)enumerator.Current); sigGen.SetHashedSubpackets(spGen.Generate()); } aOut.BeginClearText(HashAlgorithmTag.Sha256); sigGen.InitSign(PgpSignature.CanonicalTextDocument, pk); byte[] msgBytes = utf8Encoding.GetBytes(msg); sigGen.Update(msgBytes, 0, msgBytes.Length); aOut.Write(msgBytes, 0, msgBytes.Length); bOut = new BcpgOutputStream(aOut); aOut.EndClearText(); sigGen.Generate().Encode(bOut); using (BinaryReader br = new BinaryReader(result)) { br.BaseStream.Position = 0; return utf8Encoding.GetString(br.ReadBytes((int)result.Length)); } } catch (Exception e) { Console.WriteLine("This happened: " + e.Message); throw new Exception("Signing Failed: " + e.Message); } finally { try { if (privateKeyStream != null) privateKeyStream.Close(); //if(bOut != null) //bOut.Close(); //aOut.Close(); result.Close(); } catch (IOException) {} } }
public string PublicKey(string email, Dictionary<string, string> headers) { Context = new CryptoContext(Context); var publicKey = GetPublicKeyForEncryption(email); var sigKey = GetSecretKeyForSigning(email); var literalData = new PgpLiteralDataGenerator(); var data = publicKey.GetEncoded(); using (var sout = new MemoryStream()) { using (var armoredOut = new ArmoredOutputStream(sout)) { foreach (var header in headers) armoredOut.SetHeader(header.Key, header.Value); //using (var literalOut = literalData.Open( // armoredOut, // PgpLiteralData.Binary, // "email", // data.Length, // DateTime.UtcNow)) //{ // literalOut.Write(data, 0, data.Length); //} armoredOut.Write(data); } return ASCIIEncoding.ASCII.GetString(sout.ToArray()); } }
/// <summary> /// Sign data using key /// </summary> /// <param name="data">Data to sign</param> /// <param name="key">Email address of key</param> /// <returns>Returns ascii armored signature</returns> public string SignClear(string data, string key, Encoding encoding, Dictionary<string, string> headers) { Context = new CryptoContext(Context); var senderKey = GetSecretKeyForSigning(key); if (senderKey == null) throw new SecretKeyNotFoundException("Error, unable to locate signing key \"" + key + "\"."); // Setup signature stuff // var signatureData = new PgpSignatureGenerator(senderKey.PublicKey.Algorithm, HashAlgorithmTag.Sha1); signatureData.InitSign(PgpSignature.CanonicalTextDocument, senderKey.ExtractPrivateKey(Context.Password)); foreach (string userId in senderKey.PublicKey.GetUserIds()) { var subPacketGenerator = new PgpSignatureSubpacketGenerator(); subPacketGenerator.SetSignerUserId(false, userId); signatureData.SetHashedSubpackets(subPacketGenerator.Generate()); // Just the first one! break; } // // using (var sout = new MemoryStream()) { using (var armoredOut = new ArmoredOutputStream(sout)) { foreach (var header in headers) armoredOut.SetHeader(header.Key, header.Value); armoredOut.BeginClearText(HashAlgorithmTag.Sha1); // Remove any extra trailing whitespace. // this should not include \r or \n. data = data.TrimEnd(null); using (var stringReader = new StringReader(data)) { do { var line = stringReader.ReadLine(); if (line == null) break; // Lines must have all white space removed line = line.TrimEnd(null); line = line.TrimEnd(new char[] {' ', '\t', '\r', '\n'}); line += "\r\n"; signatureData.Update(encoding.GetBytes(line)); armoredOut.Write(encoding.GetBytes(line)); } while (true); } // Write extra line before signature block. armoredOut.Write(encoding.GetBytes("\r\n")); armoredOut.EndClearText(); using (var outputStream = new BcpgOutputStream(armoredOut)) { signatureData.Generate().Encode(outputStream); } } return encoding.GetString(sout.ToArray()); } }
/// <summary> /// Sign data using key /// </summary> /// <param name="data">Data to sign</param> /// <param name="key">Email address of key</param> /// <param name="headers">Headers to add to signed message</param> /// <param name="wrapLines">Automatically wrap lines that are too long</param> /// <param name="encoding">s</param> /// <returns>Returns ascii armored signature</returns> public string SignClear(string data, string key, Encoding encoding, Dictionary<string, string> headers, bool wrapLines = true) { Context = new CryptoContext(Context); PgpSecretKey senderMasterKey; var senderKey = GetSecretKeyForSigning(key, out senderMasterKey); if (senderKey == null) throw new SecretKeyNotFoundException("Error, unable to locate signing key \"" + key + "\"."); // Setup signature stuff // var signatureData = new PgpSignatureGenerator(senderKey.PublicKey.Algorithm, GetHashAlgTagFromString(Context.Digest)); signatureData.InitSign(PgpSignature.CanonicalTextDocument, senderKey.ExtractPrivateKey(Context.PasswordCallback(senderMasterKey, senderKey))); foreach (string userId in senderKey.PublicKey.GetUserIds()) { var subPacketGenerator = new PgpSignatureSubpacketGenerator(); subPacketGenerator.SetSignerUserId(false, userId); signatureData.SetHashedSubpackets(subPacketGenerator.Generate()); // Just the first one! break; } // Split any long lines if we are asked to do so. var mailLines = data.Split('\n'); if (wrapLines && mailLines.Any(line => line.Length > 70)) { var lines = new List<string>(mailLines); for (var i = 0; i < lines.Count; i++) { var line = lines[i]; if (line.Length <= 70) continue; var newLine = line.Substring(70); line = line.Substring(0, 70); lines[i] = line; lines.Insert(i + 1, newLine); } var sb = new StringBuilder(data.Length + 20); foreach (var line in lines) sb.AppendLine(line.TrimEnd('\r', '\n')); data = sb.ToString(); } // Now lets do our signing stuff using (var sout = new MemoryStream()) { using (var armoredOut = new ArmoredOutputStream(sout)) { foreach (var header in headers) armoredOut.SetHeader(header.Key, header.Value); armoredOut.BeginClearText(GetHashAlgTagFromString(Context.Digest)); // Remove any extra trailing whitespace. // this should not include \r or \n. data = data.TrimEnd(null); using (var stringReader = new StringReader(data)) { do { var line = stringReader.ReadLine(); if (line == null) break; // Lines must have all white space removed line = line.TrimEnd(null); line = line.TrimEnd(' ', '\t', '\r', '\n'); line += "\r\n"; signatureData.Update(encoding.GetBytes(line)); armoredOut.Write(encoding.GetBytes(line)); } while (true); } // Write extra line before signature block. armoredOut.Write(encoding.GetBytes("\r\n")); armoredOut.EndClearText(); using (var outputStream = new BcpgOutputStream(armoredOut)) signatureData.Generate().Encode(outputStream); } return encoding.GetString(sout.ToArray()); } }