My campaign to produce Shakespeare's Sonnets: A Graphic Novel Adaptation needs your help! Please sign up at for access to exclusive content and the opportunity to be a part of the magic!

I'm also producing a podcast discussing the sonnets, available on
industrial curiosity, itunes, spotify, stitcher, tunein and youtube!
For those who prefer reading to listening, the first 25 sonnets have been compiled into a book that is available now on Amazon and the Google Play store.

Wednesday, 4 October 2017

C# / OpenSSH RSA Encryption made easy


The struggle to uncover the secrets of importing from and export to OpenSSH keys with Microsoft's .NET RSACryptoServiceProvider is real. It's possible but not practical to do this without BouncyCastle, which may or may not be well-documented (navigating their website is far from a joyful experience), but after trawling the web and playing around I've created the following gists that should be of assistance to anyone who needs to do this in a straightforward manner.
And if you want to share RSA keys between JavaScript and .NET platforms, well, you're going to need to do this.
Import and export RSA Keys between C# and PEM format using BouncyCastle
And just because the actual encryption and decryption are always annoying:
Simple RSA Encryption to and Decryption from Base64 encoded strings in C#


  1. Hi guy!
    When i run method "runTests()", i have a problem
    System.InvalidCastException: 'Unable to cast object of type 'Org.BouncyCastle.Crypto.Parameters.RsaKeyParameters' to type 'Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair'.'

    in method:
    public static RSACryptoServiceProvider ImportPublicKey(string pem)
    var reader = new StringReader(pem);
    PemReader pr = new PemReader(reader);
    AsymmetricCipherKeyPair publicKey = (AsymmetricCipherKeyPair)pr.ReadObject();
    RSAParameters rsaParams = DotNetUtilities.ToRSAParameters((RsaKeyParameters)publicKey.Public);

    RSACryptoServiceProvider csp = new RSACryptoServiceProvider();// cspParams);
    return csp;
    Line: AsymmetricCipherKeyPair publicKey = (AsymmetricCipherKeyPair)pr.ReadObject();

    can you help fix it1
    Thank so much!

    1. Hi - your code is different to the gists, in particular your ImportPublicKey is using AsymmetricCipherKeyPair (which I use for ImportPrivateKey) whereas the gists use AsymmetricKeyParameter. Hope that helps!


Keeping Track of your Technical Debt

The impact of technical debt Over the years the concept of "technical debt" has become a phrase that can generate anxiety and a la...