Updating
This commit is contained in:
+213
@@ -0,0 +1,213 @@
|
||||
using Org.BouncyCastle.Bcpg;
|
||||
using Org.BouncyCastle.Bcpg.OpenPgp;
|
||||
using Org.BouncyCastle.Security;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Org.BouncyCastle.Utilities.IO;
|
||||
|
||||
namespace LCU.Api.Internal.FileOperations.Services
|
||||
{
|
||||
public static class CryptoHelper
|
||||
{
|
||||
private static PgpPublicKey ReadPublicKey(Stream inputStream)
|
||||
{
|
||||
inputStream = PgpUtilities.GetDecoderStream(inputStream);
|
||||
PgpPublicKeyRingBundle pgpPub = new PgpPublicKeyRingBundle(inputStream);
|
||||
|
||||
foreach (PgpPublicKeyRing keyRing in pgpPub.GetKeyRings())
|
||||
{
|
||||
foreach (PgpPublicKey key in keyRing.GetPublicKeys())
|
||||
{
|
||||
if (key.IsEncryptionKey)
|
||||
{
|
||||
return key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new ArgumentException("Can't find encryption key in key ring.");
|
||||
}
|
||||
|
||||
private static PgpPrivateKey FindSecretKey(PgpSecretKeyRingBundle pgpSec, long keyId, char[] pass)
|
||||
{
|
||||
PgpSecretKey pgpSecKey = pgpSec.GetSecretKey(keyId);
|
||||
return pgpSecKey?.ExtractPrivateKey(pass);
|
||||
}
|
||||
|
||||
public static void DecryptPgpFile(string inputFile, string outputFile, string keyFile, string passPhrase)
|
||||
{
|
||||
var encryptedFileData = File.ReadAllBytes(inputFile);
|
||||
var secretKeyData = File.ReadAllBytes(keyFile);
|
||||
var decryptedData = DecryptPgpData(encryptedFileData, secretKeyData, passPhrase);
|
||||
|
||||
File.WriteAllText(outputFile, decryptedData);
|
||||
}
|
||||
|
||||
public static string DecryptPgpData(byte[] inputData, byte[] secretKeyData, string passPhrase)
|
||||
{
|
||||
Stream inputStream = new MemoryStream(inputData);
|
||||
Stream secretKeyStream = new MemoryStream(secretKeyData);
|
||||
|
||||
string output;
|
||||
|
||||
PgpObjectFactory pgpFactory = new PgpObjectFactory(PgpUtilities.GetDecoderStream(inputStream));
|
||||
// find secret key
|
||||
PgpSecretKeyRingBundle pgpKeyRing = new PgpSecretKeyRingBundle(PgpUtilities.GetDecoderStream(secretKeyStream));
|
||||
|
||||
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;
|
||||
foreach (PgpPublicKeyEncryptedData pubKeyDataItem in encryptedData.GetEncryptedDataObjects())
|
||||
{
|
||||
privateKey = FindSecretKey(pgpKeyRing, pubKeyDataItem.KeyId, passPhrase.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();
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case PgpCompressedData data:
|
||||
{
|
||||
PgpCompressedData compressedData = data;
|
||||
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;
|
||||
using (Stream unc = literalData.GetInputStream())
|
||||
{
|
||||
output = GetString(unc);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case PgpLiteralData data:
|
||||
{
|
||||
PgpLiteralData literalData = data;
|
||||
using (Stream unc = literalData.GetInputStream())
|
||||
{
|
||||
output = GetString(unc);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case PgpOnePassSignatureList _:
|
||||
throw new PgpException("Encrypted message contains a signed message - not literal data.");
|
||||
default:
|
||||
throw new PgpException("Message is not a simple encrypted file - type unknown.");
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
public static void EncryptPgpFile(string inputFile, string outputFile, string publicKeyFile, bool applyArmor, bool withIntegrityCheck)
|
||||
{
|
||||
using (Stream publicKeyStream = File.OpenRead(publicKeyFile))
|
||||
{
|
||||
PgpPublicKey pubKey = ReadPublicKey(publicKeyStream);
|
||||
|
||||
using (MemoryStream outputBytes = new MemoryStream())
|
||||
{
|
||||
PgpCompressedDataGenerator dataCompressor = new PgpCompressedDataGenerator(CompressionAlgorithmTag.Zip);
|
||||
PgpUtilities.WriteFileToLiteralData(dataCompressor.Open(outputBytes), PgpLiteralData.Binary, new FileInfo(inputFile));
|
||||
|
||||
dataCompressor.Close();
|
||||
PgpEncryptedDataGenerator dataGenerator =
|
||||
new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Cast5, withIntegrityCheck, new SecureRandom());
|
||||
|
||||
dataGenerator.AddMethod(pubKey);
|
||||
byte[] dataBytes = outputBytes.ToArray();
|
||||
|
||||
using (Stream outputStream = File.Create(outputFile))
|
||||
{
|
||||
if (applyArmor)
|
||||
{
|
||||
using (ArmoredOutputStream armoredStream = new ArmoredOutputStream(outputStream))
|
||||
{
|
||||
WriteStream(dataGenerator.Open(armoredStream, dataBytes.Length), ref dataBytes);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteStream(dataGenerator.Open(outputStream, dataBytes.Length), ref dataBytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void WriteStream(Stream inputStream, ref byte[] dataBytes)
|
||||
{
|
||||
using (Stream outputStream = inputStream)
|
||||
{
|
||||
outputStream.Write(dataBytes, 0, dataBytes.Length);
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetString(Stream inputStream)
|
||||
{
|
||||
string output;
|
||||
using (StreamReader reader = new StreamReader(inputStream))
|
||||
{
|
||||
output = reader.ReadToEnd();
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
public static Stream GetStream(string stringData)
|
||||
{
|
||||
MemoryStream stream = new MemoryStream();
|
||||
StreamWriter writer = new StreamWriter(stream);
|
||||
writer.Write(stringData);
|
||||
writer.Flush();
|
||||
stream.Position = 0;
|
||||
return stream;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user