10

Bouncy Castle 経由で OpenPGP を使用して、インメモリ公開鍵暗号化インフラストラクチャをまとめようとしています。私たちのベンダーの 1 つは、OpenPGP 公開鍵暗号化を使用してすべてのフィードを暗号化し、私たちにも同じことを要求しているため、テクノロジーと実装に行き詰まっています。そこで、これらのフィードを自動化するための OpenPGP 暗号化/復号化ツールキットをコーディングしています。

bouncycastle.org の例では、暗号化されたデータをファイル システムに書き込み、ファイル システムからキーを収集することがデフォルトになっています。これは私がやりたいことではないので、すべてをストリームベースにしようとしてきました。

実際にコードをコンパイルして実行できるところまで来ましたが、暗号化されたペイロードは空です。何かばかげたことを見逃していると思いますが、あれこれ試して数日経った後、これを客観的に調べる能力を失いました。

私のユーティリティ クラスには、次のメソッドが含まれています。

    public static PgpPublicKey ImportPublicKey(
        this Stream publicIn)
    {
        var pubRings =
            new PgpPublicKeyRingBundle(PgpUtilities.GetDecoderStream(publicIn)).GetKeyRings().OfType<PgpPublicKeyRing>();
        var pubKeys = pubRings.SelectMany(x => x.GetPublicKeys().OfType<PgpPublicKey>());
        var pubKey = pubKeys.FirstOrDefault();
        return pubKey;
    }

    public static Stream Streamify(this string theString, Encoding encoding = null)
    {
        encoding = encoding ?? Encoding.UTF8;
        var stream = new MemoryStream(encoding.GetBytes(theString));
        return stream;
    }

    public static string Stringify(this Stream theStream,
                                   Encoding encoding = null)
    {
        encoding = encoding ?? Encoding.UTF8;
        using (var reader = new StreamReader(theStream, encoding))
        {
            return reader.ReadToEnd();
        }
    }

    public static byte[] ReadFully(this Stream stream)
    {
        if (!stream.CanRead) throw new ArgumentException("This is not a readable stream.");
        var buffer = new byte[32768];
        using (var ms = new MemoryStream())
        {
            while (true)
            {
                var read = stream.Read(buffer, 0, buffer.Length);
                if (read <= 0)
                    return ms.ToArray();
                ms.Write(buffer, 0, read);
            }
        }
    }

    public static void PgpEncrypt(
        this Stream toEncrypt,
        Stream outStream,
        PgpPublicKey encryptionKey,
        bool armor = true,
        bool verify = true,
        CompressionAlgorithmTag compressionAlgorithm = CompressionAlgorithmTag.Zip)
    {
        if (armor) outStream = new ArmoredOutputStream(outStream);
        var compressor = new PgpCompressedDataGenerator(CompressionAlgorithmTag.Zip);
        outStream = compressor.Open(outStream);
        var data = toEncrypt.ReadFully();
        var encryptor = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Cast5, verify, new SecureRandom());
        encryptor.AddMethod(encryptionKey);
        outStream = encryptor.Open(outStream, data.Length);
        outStream.Write(data, 0, data.Length);
    }

私のテスト方法は次のようになります。

    private static void EncryptMessage()
    {
        var pubKey = @"<public key text>";

        var clearText = "This is an encrypted message.  There are many like it but this one is cryptic.";
        using (var stream = pubKey.Streamify())
        {
            var key = stream.ImportPublicKey();
            using (var clearStream = clearText.Streamify())
            using (var cryptoStream = new MemoryStream())
            {
                clearStream.PgpEncrypt(cryptoStream,key);
                cryptoStream.Position = 0;
                Console.WriteLine(cryptoStream.Stringify());
                Console.WriteLine("Press any key to continue.");
            }
        }
        Console.ReadKey();
    }

私が得る結果は次のようになります。

-----BEGIN PGP MESSAGE-----
Version: BCPG C# v1.7.4114.6378


Press any key to continue.

誰かが私が間違っていることを教えてもらえますか?

4

1 に答える 1