0

I am generating a public key and secret Key and want to save the public key in a string field.Saving it to the file works fine. but how do I get it into a string...

    private string SaveAndReturn(PgpPublicKey publicKey, bool armor = true)
    {
        var fileStream = new FileInfo($@"C:\encrypt\Keys\pub2.asc").OpenWrite() as Stream;
        SaveFile(publicKey, fileStream, armor);
        fileStream.Close();
        var keyString = GetStringFromKey(publicKey);
        return keyString;
    }

    public void SaveFile(PgpPublicKey publicKey, Stream outStream, bool armor = true)
    {
        if (armor)
        {
            outStream = new ArmoredOutputStream(outStream);
        }
        publicKey.Encode(outStream);
        outStream.Close();

    }

    private string GetStringFromKey(PgpPublicKey publicKey)
    {
        var armor = true;
        var stream = new MemoryStream() as Stream;
        publicKey.Encode(stream);
        stream.Position = 0;
        var keyString = GetString(stream);
        stream.Close();
        Console.WriteLine(keyString);
        return keyString;
    }
    private string GetString(Stream theStream, Encoding encoding = null)
    {
        encoding = encoding ?? Encoding.UTF8;
        using (var reader = new StreamReader(theStream, encoding))
        {
            return reader.ReadToEnd();
        }
    }

The pub2.asc file is created fine and has the in there. Instead of saving the key into a file, I want it into a string.. and the following code gives me an empty string. What am I doing wrong? So, I updated the code to set the position before reading the stream. But the string returned is not the same as the text I see in file. I think ArmoredOutputStream does Base64 encoding. How to I get the same string as in text file

String from the above code:

???z}?.?u?l:?|?5 ?test?? Wh?? $???_??cH???L~??+??Bc$?rN??g?.??m?s????0?Z???k?-??G??mzBQ$ U?E??V|/?,l???=???p???? ??5?%%?9??ae?S?|8Lh?\???|pB??G*?8????N9'???+(?|R??Q@R??_9D

If I use ASCII encoding, the string is

??Wh{? ??;cgx??hO)???C?~????t?roS?4??:??????E?fF?U?r?+?=?p???#L?????a??B}????-.o??q?i5???Ff.??6???????6r?HdX??}?S???4?(j)3 ?test?? Wh? ?U?+U???????????v??????BJEwp*0?'?lz2??6??P,A???Q??2M??3?a?W??9???*????M%?|?U^>??????q?&??V??N

Text from Pub2.asc file

-----BEGIN PGP PUBLIC KEY BLOCK----- Version: BCPG C# v1.8.1.0

mIsEV2h5lwEEAJakqTE+XcRBQ0b2P2vjNuDrgi9IcCsgEGdD3bpH6d1W8CSR+YkZ EV/PwmNI1dyh8Ex+zqHQKwaPCIfEQhNjF2sIJKVyTtjpZ4YukoRto3PBjdse0zAB 2Freiv7Ha9ct0wSQRwID2haKbXpCUSQN5/j8xbx90y60ddxsOoV8C7A1AAUTtAR0 ZXN0iJwEEAECAAYFAldosdcACgkQPIdhk1pxnGAhxwQAg4NRYbuSDg5WVw3G1tVm 1xM746+O5J6B5RHnaQvFePpVVUm/tpLyCbHPNeYlJao5FeHRYWWpU4d8OExo4phc iv7JfHBCx9tHKso4uccS3ROaTjknw+jwuLErKLN8UvjaUUBSn8wVXzlEDVXSRYCt Vnwv/Sxsxe7mgT2qBJSYcKY= =PYEC -----END PGP PUBLIC KEY BLOCK-----

katie77
  • 1,797
  • 4
  • 25
  • 43
  • You are using `ArmoredOutputStream` when writing the file, but a `MemoryStream as Stream()` on the string? In your get string method, try setting `stream` to a new `ArmoredOutputStream` like `var stream = new ArmoredOutputStream(stream);` as a quick hack to see what we get – ethorn10 Jun 21 '16 at 03:36
  • I tried adding this var stream = new MemoryStream() as Stream; stream = new ArmoredInputStream(stream); Once I run this, I get Exception thrown: 'System.NotSupportedException' in BouncyCastle.Crypto.dll on the next line publicKey.Encode(stream); – katie77 Jun 21 '16 at 03:42
  • `ArmoredOutputStream` not `ArmoredInputStream` – ethorn10 Jun 21 '16 at 03:46
  • Sorry... I did not even notice input stream( its too late for me). When I Use a ArmoredOutputStream, I get same exception on trying to set the position. var stream = new MemoryStream() as Stream; stream = new ArmoredOutputStream(stream); publicKey.Encode(stream); stream.Position = 0; – katie77 Jun 21 '16 at 04:05

1 Answers1

0

The position of the MemoryStream is still set to the end of the string you wrote into it. You need to reset the position to 0 before you try to read from it again. You can do this in the calling code or in GetString() directly. Here is the fix in the calling code:

private string GetStringFromKey(PgpPublicKey publicKey)
{
    var armor = true;
    var stream = new MemoryStream() as Stream;
    publicKey.Encode(stream);
 -->stream.Position = 0;
    var keyString = GetString(stream);
    stream.Close();
    Console.WriteLine(keyString);
    return keyString;
}

You may also find some useful information over at How do you get a string from a MemoryStream?

Community
  • 1
  • 1
gnalck
  • 972
  • 6
  • 12