Leo*_*Leo 20 c# encryption pgp public-key-encryption public-key
我已经研究了一些关于如何实现我在问题中所说的内容并发现了几个API,但大多数API看起来非常复杂,因为我只是在这方面的一个noobie我只想要一个简单的方法,如:
public String Encrypt(String message, PublicKey publicKey)
Run Code Online (Sandbox Code Playgroud)
不知道是否可以这样做?如果没有那么请有人开导我另一种方式来实现这个:)
谢谢.
更新:
到目前为止,我只看到OpenPGP加密的所有库都需要公钥和私钥才能进行加密,而我只想用公钥加密(因为我没有私钥来使用它) !
Leo*_*Leo 10
我在这里找到了一个教程,但它需要密钥和公钥来加密数据.然而,我已经修改了一些代码只需要公钥(没有签名,没有压缩),并认为我应该在这里发布它,以防有人也在寻找这个问题的解决方案.Belows是修改后的代码,作者的所有学分 - 金先生.
public class PgpEncrypt
{
private PgpEncryptionKeys m_encryptionKeys;
private const int BufferSize = 0x10000;
/// <summary>
/// Instantiate a new PgpEncrypt class with initialized PgpEncryptionKeys.
/// </summary>
/// <param name="encryptionKeys"></param>
/// <exception cref="ArgumentNullException">encryptionKeys is null</exception>
public PgpEncrypt(PgpEncryptionKeys encryptionKeys)
{
if (encryptionKeys == null)
{
throw new ArgumentNullException("encryptionKeys", "encryptionKeys is null.");
}
m_encryptionKeys = encryptionKeys;
}
/// <summary>
/// Encrypt and sign the file pointed to by unencryptedFileInfo and
/// write the encrypted content to outputStream.
/// </summary>
/// <param name="outputStream">The stream that will contain the
/// encrypted data when this method returns.</param>
/// <param name="fileName">FileInfo of the file to encrypt</param>
public void Encrypt(Stream outputStream, FileInfo unencryptedFileInfo)
{
if (outputStream == null)
{
throw new ArgumentNullException("outputStream", "outputStream is null.");
}
if (unencryptedFileInfo == null)
{
throw new ArgumentNullException("unencryptedFileInfo", "unencryptedFileInfo is null.");
}
if (!File.Exists(unencryptedFileInfo.FullName))
{
throw new ArgumentException("File to encrypt not found.");
}
using (Stream encryptedOut = ChainEncryptedOut(outputStream))
{
using (Stream literalOut = ChainLiteralOut(encryptedOut, unencryptedFileInfo))
using (FileStream inputFile = unencryptedFileInfo.OpenRead())
{
WriteOutput(literalOut, inputFile);
}
}
}
private static void WriteOutput(Stream literalOut,
FileStream inputFile)
{
int length = 0;
byte[] buf = new byte[BufferSize];
while ((length = inputFile.Read(buf, 0, buf.Length)) > 0)
{
literalOut.Write(buf, 0, length);
}
}
private Stream ChainEncryptedOut(Stream outputStream)
{
PgpEncryptedDataGenerator encryptedDataGenerator;
encryptedDataGenerator =
new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.TripleDes,
new SecureRandom());
encryptedDataGenerator.AddMethod(m_encryptionKeys.PublicKey);
return encryptedDataGenerator.Open(outputStream, new byte[BufferSize]);
}
private static Stream ChainLiteralOut(Stream encryptedOut, FileInfo file)
{
PgpLiteralDataGenerator pgpLiteralDataGenerator = new PgpLiteralDataGenerator();
return pgpLiteralDataGenerator.Open(encryptedOut, PgpLiteralData.Binary,
file);
}
}
Run Code Online (Sandbox Code Playgroud)
当然要运行这些代码,您必须在项目中包含BouncyCastle库.
我已经测试过加密然后解密,它运行良好:)
这可能是一种更清洁的方法:
var pkr = asciiPublicKeyToRing(ascfilein);
if (pkr != null)
{
try
{
EncryptFile(
tbUnencryptedFile.Text, tbEncryptedFile.Text, getFirstPublicEncryptionKeyFromRing(pkr), true, true);
MessageBox.Show("File Encrypted.");
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message);
}
}
else
{
MessageBox.Show(ascfilein + " is not a public key.");
}
Run Code Online (Sandbox Code Playgroud)
private PgpPublicKeyRing asciiPublicKeyToRing(string ascfilein)
{
using (Stream pubFis = File.OpenRead(ascfilein))
{
var pubArmoredStream = new ArmoredInputStream(pubFis);
PgpObjectFactory pgpFact = new PgpObjectFactory(pubArmoredStream);
Object opgp = pgpFact.NextPgpObject();
var pkr = opgp as PgpPublicKeyRing;
return pkr;
}
}
private PgpPublicKey getFirstPublicEncryptionKeyFromRing(PgpPublicKeyRing pkr)
{
foreach (PgpPublicKey k in pkr.GetPublicKeys())
{
if (k.IsEncryptionKey)
return k;
}
throw new ArgumentException("Can't find encryption key in key ring.");
}
public static void EncryptFile(string inputFile, string outputFile, PgpPublicKey encKey, bool armor,
bool withIntegrityCheck)
{
using (MemoryStream bOut = new MemoryStream())
{
PgpCompressedDataGenerator comData = new PgpCompressedDataGenerator(CompressionAlgorithmTag.Zip);
PgpUtilities.WriteFileToLiteralData(comData.Open(bOut), PgpLiteralData.Binary,
new FileInfo(inputFile));
comData.Close();
PgpEncryptedDataGenerator cPk = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Aes256,
withIntegrityCheck, new SecureRandom());
cPk.AddMethod(encKey);
byte[] bytes = bOut.ToArray();
using (Stream outputStream = File.Create(outputFile))
{
if (armor)
{
using (ArmoredOutputStream armoredStream = new ArmoredOutputStream(outputStream))
using (Stream cOut = cPk.Open(armoredStream, bytes.Length))
{
cOut.Write(bytes, 0, bytes.Length);
}
}
else
{
using (Stream cOut = cPk.Open(outputStream, bytes.Length))
{
cOut.Write(bytes, 0, bytes.Length);
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
你看过bouncycastle pgp了吗?http://www.bouncycastle.org/
这里有一个源代码示例,用于获取从BouncyCastle站点获取的文件:需要C#中的BouncyCastle PGP文件加密示例
如果你想在 dotnet core 中同时进行加密和解密,这是我遵循的文章:https ://nightbaker.github.io/pgp/cryptography/.net/core/2019/02/08/pgp-encryption/
加密部分不需要私钥。
所有作品均归原作者 NightBaker 所有。
Install-Package BouncyCastle.NetCore
Install-Package BouncyCastle.NetCoreSdk
Run Code Online (Sandbox Code Playgroud)
Install-Package BouncyCastle.NetCore
Install-Package BouncyCastle.NetCoreSdk
Run Code Online (Sandbox Code Playgroud)
用法:
public class Pgp
{
public static void EncryptFile(
string outputFileName,
string inputFileName,
string encKeyFileName,
bool armor,
bool withIntegrityCheck)
{
PgpPublicKey encKey = PgpExampleUtilities.ReadPublicKey(encKeyFileName);
using (Stream output = File.Create(outputFileName))
{
EncryptFile(output, inputFileName, encKey, armor, withIntegrityCheck);
}
}
private static void EncryptFile(
Stream outputStream,
string fileName,
PgpPublicKey encKey,
bool armor,
bool withIntegrityCheck)
{
if (armor)
{
outputStream = new ArmoredOutputStream(outputStream);
}
try
{
byte[] bytes = PgpExampleUtilities.CompressFile(fileName, CompressionAlgorithmTag.Zip);
PgpEncryptedDataGenerator encGen = new PgpEncryptedDataGenerator(
SymmetricKeyAlgorithmTag.Cast5, withIntegrityCheck, new SecureRandom());
encGen.AddMethod(encKey);
Stream cOut = encGen.Open(outputStream, bytes.Length);
cOut.Write(bytes, 0, bytes.Length);
cOut.Close();
if (armor)
{
outputStream.Close();
}
}
catch (PgpException e)
{
Console.Error.WriteLine(e);
Exception underlyingException = e.InnerException;
if (underlyingException != null)
{
Console.Error.WriteLine(underlyingException.Message);
Console.Error.WriteLine(underlyingException.StackTrace);
}
}
}
}
public class PgpExampleUtilities
{
internal static PgpPublicKey ReadPublicKey(string fileName)
{
using (Stream keyIn = File.OpenRead(fileName))
{
return ReadPublicKey(keyIn);
}
}
internal static PgpPublicKey ReadPublicKey(Stream input)
{
PgpPublicKeyRingBundle pgpPub = new PgpPublicKeyRingBundle(
PgpUtilities.GetDecoderStream(input));
//
// 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 (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.");
}
internal static byte[] CompressFile(string fileName, CompressionAlgorithmTag algorithm)
{
MemoryStream bOut = new MemoryStream();
PgpCompressedDataGenerator comData = new PgpCompressedDataGenerator(algorithm);
PgpUtilities.WriteFileToLiteralData(comData.Open(bOut), PgpLiteralData.Binary,
new FileInfo(fileName));
comData.Close();
return bOut.ToArray();
}
}
Run Code Online (Sandbox Code Playgroud)