summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2022-06-29 14:15:10 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2022-06-29 14:15:10 +0700
commit435210f10fd927653ce8fbc04ec537ae5d8966b6 (patch)
tree27b6ed1c029db271c3429ac57629d7f0156c5fed
parentRefactoring around Platform (diff)
downloadBouncyCastle.NET-ed25519-435210f10fd927653ce8fbc04ec537ae5d8966b6.tar.xz
Generics migration complete
-rw-r--r--crypto/src/crypto/parameters/ECKeyParameters.cs20
-rw-r--r--crypto/src/openssl/PEMReader.cs48
-rw-r--r--crypto/src/pkix/PkixAttrCertPathBuilder.cs6
-rw-r--r--crypto/src/pkix/PkixCertPathBuilder.cs6
-rw-r--r--crypto/src/pkix/PkixParameters.cs97
-rw-r--r--crypto/src/pkix/Rfc3281CertPathUtilities.cs87
-rw-r--r--crypto/src/security/AgreementUtilities.cs41
-rw-r--r--crypto/src/security/CipherUtilities.cs838
-rw-r--r--crypto/src/security/DigestUtilities.cs373
-rw-r--r--crypto/src/security/DotNetUtilities.cs6
-rw-r--r--crypto/src/security/GeneratorUtilities.cs85
-rw-r--r--crypto/src/security/MacUtilities.cs158
-rw-r--r--crypto/src/security/ParameterUtilities.cs53
-rw-r--r--crypto/src/security/PbeUtilities.cs421
-rw-r--r--crypto/src/security/PrivateKeyFactory.cs2
-rw-r--r--crypto/src/security/PublicKeyFactory.cs4
-rw-r--r--crypto/src/security/SecureRandom.cs11
-rw-r--r--crypto/src/security/SignerUtilities.cs889
-rw-r--r--crypto/src/security/WrapperUtilities.cs68
-rw-r--r--crypto/src/tsp/TSPAlgorithms.cs15
-rw-r--r--crypto/src/tsp/TSPUtil.cs132
-rw-r--r--crypto/src/tsp/TimeStampRequest.cs11
-rw-r--r--crypto/src/tsp/TimeStampResponseGenerator.cs20
-rw-r--r--crypto/src/tsp/TimeStampToken.cs5
-rw-r--r--crypto/src/tsp/TimeStampTokenGenerator.cs13
-rw-r--r--crypto/src/util/Platform.cs102
-rw-r--r--crypto/src/util/collections/CollectionUtilities.cs34
-rw-r--r--crypto/src/util/collections/EmptyEnumerable.cs44
-rw-r--r--crypto/src/util/collections/EnumerableProxy.cs35
-rw-r--r--crypto/src/util/collections/HashSet.cs99
-rw-r--r--crypto/src/util/collections/ISet.cs19
-rw-r--r--crypto/src/util/collections/ReadOnlyCollection.cs44
-rw-r--r--crypto/src/util/collections/ReadOnlyDictionary.cs64
-rw-r--r--crypto/src/util/collections/ReadOnlyList.cs5
-rw-r--r--crypto/src/util/collections/ReadOnlySet.cs61
-rw-r--r--crypto/src/util/collections/UnmodifiableDictionary.cs64
-rw-r--r--crypto/src/util/collections/UnmodifiableDictionaryProxy.cs66
-rw-r--r--crypto/src/util/collections/UnmodifiableList.cs67
-rw-r--r--crypto/src/util/collections/UnmodifiableListProxy.cs61
-rw-r--r--crypto/src/util/collections/UnmodifiableSet.cs59
-rw-r--r--crypto/src/util/collections/UnmodifiableSetProxy.cs56
-rw-r--r--crypto/src/util/io/pem/PemObject.cs18
-rw-r--r--crypto/src/util/io/pem/PemReader.cs25
-rw-r--r--crypto/src/util/io/pem/PemWriter.cs1
-rw-r--r--crypto/src/x509/SubjectPublicKeyInfoFactory.cs4
-rw-r--r--crypto/src/x509/X509CertPairParser.cs19
-rw-r--r--crypto/src/x509/X509Certificate.cs4
-rw-r--r--crypto/src/x509/X509Crl.cs27
-rw-r--r--crypto/src/x509/X509CrlEntry.cs5
-rw-r--r--crypto/src/x509/X509V1CertificateGenerator.cs4
-rw-r--r--crypto/src/x509/X509V2AttributeCertificate.cs14
-rw-r--r--crypto/src/x509/X509V2AttributeCertificateGenerator.cs6
-rw-r--r--crypto/src/x509/X509V2CRLGenerator.cs12
-rw-r--r--crypto/src/x509/extension/X509ExtensionUtil.cs65
-rw-r--r--crypto/src/x509/store/X509AttrCertStoreSelector.cs50
-rw-r--r--crypto/src/x509/store/X509CertStoreSelector.cs15
-rw-r--r--crypto/src/x509/store/X509CrlStoreSelector.cs10
-rw-r--r--crypto/test/src/asn1/test/AttributeTableUnitTest.cs2
-rw-r--r--crypto/test/src/asn1/test/X509NameTest.cs1
-rw-r--r--crypto/test/src/cmp/test/ProtectedMessageTest.cs3
-rw-r--r--crypto/test/src/cms/test/CMSTestUtil.cs2
-rw-r--r--crypto/test/src/crmf/test/CrmfTest.cs5
-rw-r--r--crypto/test/src/crypto/prng/test/DrbgTestVector.cs4
-rw-r--r--crypto/test/src/crypto/test/GOST3411_2012_256DigestTest.cs3
-rw-r--r--crypto/test/src/crypto/test/GOST3411_2012_512DigestTest.cs1
-rw-r--r--crypto/test/src/crypto/test/NistEccTest.cs8
-rw-r--r--crypto/test/src/crypto/test/cavp/CavpReader.cs37
-rw-r--r--crypto/test/src/crypto/test/cavp/KDFCounterTests.cs6
-rw-r--r--crypto/test/src/crypto/test/cavp/KDFDoublePipelineTests.cs5
-rw-r--r--crypto/test/src/crypto/test/cavp/KDFFeedbackCounterTests.cs5
-rw-r--r--crypto/test/src/math/ec/test/ECAlgorithmsTest.cs13
-rw-r--r--crypto/test/src/math/ec/test/ECPointPerformanceTest.cs2
-rw-r--r--crypto/test/src/math/ec/test/ECPointTest.cs3
-rw-r--r--crypto/test/src/math/ec/test/FixedPointTest.cs2
-rw-r--r--crypto/test/src/openpgp/test/IgnoreMarkerPacketInCertificatesTest.cs16
-rw-r--r--crypto/test/src/openpgp/test/PGPClearSignedSignatureTest.cs6
-rw-r--r--crypto/test/src/openpgp/test/PGPDSATest.cs5
-rw-r--r--crypto/test/src/openpgp/test/PGPRSATest.cs41
-rw-r--r--crypto/test/src/openpgp/test/PgpECDHTest.cs6
-rw-r--r--crypto/test/src/openpgp/test/PgpECDsaTest.cs6
-rw-r--r--crypto/test/src/openpgp/test/PgpKeyRingTest.cs7
-rw-r--r--crypto/test/src/openpgp/test/PgpSignatureInvalidVersionIgnoredTest.cs1
-rw-r--r--crypto/test/src/pkcs/test/PKCS10Test.cs2
-rw-r--r--crypto/test/src/pkcs/test/PKCS12StoreTest.cs1
-rw-r--r--crypto/test/src/security/test/TestDotNetUtil.cs1
-rw-r--r--crypto/test/src/security/test/TestEncodings.cs4
-rw-r--r--crypto/test/src/security/test/TestSignerUtil.cs12
-rw-r--r--crypto/test/src/test/BlockCipherTest.cs9
-rw-r--r--crypto/test/src/test/CertPathTest.cs1
-rw-r--r--crypto/test/src/test/CertPathValidatorTest.cs1
-rw-r--r--crypto/test/src/test/CertTest.cs9
-rw-r--r--crypto/test/src/test/NamedCurveTest.cs6
-rw-r--r--crypto/test/src/test/NistCertPathTest.cs5
-rw-r--r--crypto/test/src/test/PKCS10CertRequestTest.cs1
-rw-r--r--crypto/test/src/test/PkixPolicyMappingTest.cs1
-rw-r--r--crypto/test/src/test/PkixTest.cs3
-rw-r--r--crypto/test/src/test/X509StoreTest.cs4
-rw-r--r--crypto/test/src/test/nist/NistCertPathTest.cs59
-rw-r--r--crypto/test/src/test/nist/NistCertPathTest2.cs75
-rw-r--r--crypto/test/src/tls/test/MockDatagramAssociation.cs13
-rw-r--r--crypto/test/src/tsp/test/NewTspTest.cs20
-rw-r--r--crypto/test/src/tsp/test/TSPTest.cs4
-rw-r--r--crypto/test/src/tsp/test/TSPTestUtil.cs133
-rw-r--r--crypto/test/src/util/io/pem/test/AllTests.cs24
-rw-r--r--crypto/test/src/util/test/SimpleTest.cs6
-rw-r--r--crypto/test/src/x509/test/TestCertificateGen.cs1
106 files changed, 2113 insertions, 3040 deletions
diff --git a/crypto/src/crypto/parameters/ECKeyParameters.cs b/crypto/src/crypto/parameters/ECKeyParameters.cs
index 07165ead1..ed8537f3d 100644
--- a/crypto/src/crypto/parameters/ECKeyParameters.cs
+++ b/crypto/src/crypto/parameters/ECKeyParameters.cs
@@ -1,17 +1,27 @@
 using System;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.X9;
 using Org.BouncyCastle.Crypto.Generators;
 using Org.BouncyCastle.Security;
-using Org.BouncyCastle.Utilities;
 
 namespace Org.BouncyCastle.Crypto.Parameters
 {
     public abstract class ECKeyParameters
         : AsymmetricKeyParameter
     {
-        private static readonly string[] algorithms = { "EC", "ECDSA", "ECDH", "ECDHC", "ECGOST3410", "ECMQV" };
+        // NB: Use a Dictionary so we can lookup the upper case version
+        private static readonly Dictionary<string, string> Algorithms =
+            new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
+        {
+            { "EC", "EC" },
+            { "ECDSA", "ECDSA" },
+            { "ECDH", "ECDH" },
+            { "ECDHC", "ECDHC" },
+            { "ECGOST3410", "ECGOST3410" },
+            { "ECMQV", "ECMQV" },
+        };
 
         private readonly string algorithm;
         private readonly ECDomainParameters parameters;
@@ -101,9 +111,9 @@ namespace Org.BouncyCastle.Crypto.Parameters
 
         internal static string VerifyAlgorithmName(string algorithm)
         {
-            string upper = Platform.ToUpperInvariant(algorithm);
-            if (Array.IndexOf(algorithms, algorithm, 0, algorithms.Length) < 0)
-                throw new ArgumentException("unrecognised algorithm: " + algorithm, "algorithm");
+            if (!Algorithms.TryGetValue(algorithm, out var upper))
+                throw new ArgumentException("unrecognised algorithm: " + algorithm, nameof(algorithm));
+
             return upper;
         }
 
diff --git a/crypto/src/openssl/PEMReader.cs b/crypto/src/openssl/PEMReader.cs
index 5b4e37035..1ba7165b3 100644
--- a/crypto/src/openssl/PEMReader.cs
+++ b/crypto/src/openssl/PEMReader.cs
@@ -1,23 +1,20 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.Diagnostics;
 using System.IO;
-using System.Text;
 
 using Org.BouncyCastle.Asn1;
-using Org.BouncyCastle.Asn1.Nist;
 using Org.BouncyCastle.Asn1.Pkcs;
 using Org.BouncyCastle.Asn1.Sec;
-using Org.BouncyCastle.Asn1.TeleTrust;
 using Org.BouncyCastle.Asn1.X509;
 using Org.BouncyCastle.Asn1.X9;
 using Org.BouncyCastle.Crypto;
-using Org.BouncyCastle.Crypto.EC;
 using Org.BouncyCastle.Crypto.Generators;
 using Org.BouncyCastle.Crypto.Parameters;
 using Org.BouncyCastle.Pkcs;
 using Org.BouncyCastle.Security;
 using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Collections;
 using Org.BouncyCastle.Utilities.Encoders;
 using Org.BouncyCastle.Utilities.IO.Pem;
 using Org.BouncyCastle.X509;
@@ -34,25 +31,25 @@ namespace Org.BouncyCastle.OpenSsl
     public class PemReader
         : Org.BouncyCastle.Utilities.IO.Pem.PemReader
     {
-//		private static readonly IDictionary parsers = new Hashtable();
+        //private static readonly Dictionary<string, PemObjectParser> Parsers = new Dictionary<string, PemObjectParser>();
 
         static PemReader()
         {
-//			parsers.Add("CERTIFICATE REQUEST", new PKCS10CertificationRequestParser());
-//			parsers.Add("NEW CERTIFICATE REQUEST", new PKCS10CertificationRequestParser());
-//			parsers.Add("CERTIFICATE", new X509CertificateParser(provider));
-//			parsers.Add("X509 CERTIFICATE", new X509CertificateParser(provider));
-//			parsers.Add("X509 CRL", new X509CRLParser(provider));
-//			parsers.Add("PKCS7", new PKCS7Parser());
-//			parsers.Add("ATTRIBUTE CERTIFICATE", new X509AttributeCertificateParser());
-//			parsers.Add("EC PARAMETERS", new ECNamedCurveSpecParser());
-//			parsers.Add("PUBLIC KEY", new PublicKeyParser(provider));
-//			parsers.Add("RSA PUBLIC KEY", new RSAPublicKeyParser(provider));
-//			parsers.Add("RSA PRIVATE KEY", new RSAKeyPairParser(provider));
-//			parsers.Add("DSA PRIVATE KEY", new DSAKeyPairParser(provider));
-//			parsers.Add("EC PRIVATE KEY", new ECDSAKeyPairParser(provider));
-//			parsers.Add("ENCRYPTED PRIVATE KEY", new EncryptedPrivateKeyParser(provider));
-//			parsers.Add("PRIVATE KEY", new PrivateKeyParser(provider));
+//			Parsers.Add("CERTIFICATE REQUEST", new PKCS10CertificationRequestParser());
+//			Parsers.Add("NEW CERTIFICATE REQUEST", new PKCS10CertificationRequestParser());
+//			Parsers.Add("CERTIFICATE", new X509CertificateParser(provider));
+//			Parsers.Add("X509 CERTIFICATE", new X509CertificateParser(provider));
+//			Parsers.Add("X509 CRL", new X509CRLParser(provider));
+//			Parsers.Add("PKCS7", new PKCS7Parser());
+//			Parsers.Add("ATTRIBUTE CERTIFICATE", new X509AttributeCertificateParser());
+//			Parsers.Add("EC PARAMETERS", new ECNamedCurveSpecParser());
+//			Parsers.Add("PUBLIC KEY", new PublicKeyParser(provider));
+//			Parsers.Add("RSA PUBLIC KEY", new RSAPublicKeyParser(provider));
+//			Parsers.Add("RSA PRIVATE KEY", new RSAKeyPairParser(provider));
+//			Parsers.Add("DSA PRIVATE KEY", new DSAKeyPairParser(provider));
+//			Parsers.Add("EC PRIVATE KEY", new ECDSAKeyPairParser(provider));
+//			Parsers.Add("ENCRYPTED PRIVATE KEY", new EncryptedPrivateKeyParser(provider));
+//			Parsers.Add("PRIVATE KEY", new PrivateKeyParser(provider));
         }
 
         private readonly IPasswordFinder pFinder;
@@ -238,13 +235,13 @@ namespace Org.BouncyCastle.OpenSsl
             string type = pemObject.Type.Substring(0, pemObject.Type.Length - "PRIVATE KEY".Length).Trim();
             byte[] keyBytes = pemObject.Content;
 
-            IDictionary fields = Platform.CreateHashtable();
+            var fields = new Dictionary<string, string>();
             foreach (PemHeader header in pemObject.Headers)
             {
                 fields[header.Name] = header.Value;
             }
 
-            string procType = (string) fields["Proc-Type"];
+            string procType = CollectionUtilities.GetValueOrNull(fields, "Proc-Type");
 
             if (procType == "4,ENCRYPTED")
             {
@@ -252,11 +249,12 @@ namespace Org.BouncyCastle.OpenSsl
                     throw new PasswordException("No password finder specified, but a password is required");
 
                 char[] password = pFinder.GetPassword();
-
                 if (password == null)
                     throw new PasswordException("Password is null, but a password is required");
 
-                string dekInfo = (string) fields["DEK-Info"];
+                if (!fields.TryGetValue("DEK-Info", out var dekInfo))
+                    throw new PemException("missing DEK-info");
+
                 string[] tknz = dekInfo.Split(',');
 
                 string dekAlgName = tknz[0].Trim();
diff --git a/crypto/src/pkix/PkixAttrCertPathBuilder.cs b/crypto/src/pkix/PkixAttrCertPathBuilder.cs
index b10f64d6b..c583bff00 100644
--- a/crypto/src/pkix/PkixAttrCertPathBuilder.cs
+++ b/crypto/src/pkix/PkixAttrCertPathBuilder.cs
@@ -161,17 +161,17 @@ namespace Org.BouncyCastle.Pkix
 					}
 
 					// try to get the issuer certificate from one of the stores
-					ISet issuers = new HashSet();
+					ISet<X509Certificate> issuers;
 					try
 					{
-						issuers.AddAll(PkixCertPathValidatorUtilities.FindIssuerCerts(tbvCert, pkixParams));
+						issuers = PkixCertPathValidatorUtilities.FindIssuerCerts(tbvCert, pkixParams);
 					}
 					catch (Exception e)
 					{
 						throw new Exception("Cannot find issuer certificate for certificate in certification path.", e);
 					}
 
-					if (issuers.IsEmpty)
+					if (issuers.Count < 1)
 						throw new Exception("No issuer certificate for certificate in certification path found.");
 
 					foreach (X509Certificate issuer in issuers)
diff --git a/crypto/src/pkix/PkixCertPathBuilder.cs b/crypto/src/pkix/PkixCertPathBuilder.cs
index a0abcc888..908444a73 100644
--- a/crypto/src/pkix/PkixCertPathBuilder.cs
+++ b/crypto/src/pkix/PkixCertPathBuilder.cs
@@ -131,17 +131,17 @@ namespace Org.BouncyCastle.Pkix
 					}
 
 					// try to get the issuer certificate from one of the stores
-					HashSet issuers = new HashSet();
+					ISet<X509Certificate> issuers;
 					try
 					{
-						issuers.AddAll(PkixCertPathValidatorUtilities.FindIssuerCerts(tbvCert, pkixParams));
+						issuers = PkixCertPathValidatorUtilities.FindIssuerCerts(tbvCert, pkixParams);
 					}
 					catch (Exception e)
 					{
 						throw new Exception("Cannot find issuer certificate for certificate in certification path.", e);
 					}
 
-					if (issuers.IsEmpty)
+					if (issuers.Count < 1)
 						throw new Exception("No issuer certificate for certificate in certification path found.");
 
 					foreach (X509Certificate issuer in issuers)
diff --git a/crypto/src/pkix/PkixParameters.cs b/crypto/src/pkix/PkixParameters.cs
index cafa1115c..8e4c609ed 100644
--- a/crypto/src/pkix/PkixParameters.cs
+++ b/crypto/src/pkix/PkixParameters.cs
@@ -56,10 +56,10 @@ namespace Org.BouncyCastle.Pkix
 		private ISelector<X509Certificate> m_targetConstraintsCert;
 
 		private bool additionalLocationsEnabled;
-		private ISet trustedACIssuers;
-		private ISet necessaryACAttributes;
-		private ISet prohibitedACAttributes;
-		private ISet attrCertCheckers;
+		private ISet<TrustAnchor> trustedACIssuers;
+		private ISet<string> necessaryACAttributes;
+		private ISet<string> prohibitedACAttributes;
+		private ISet<PkixAttrCertChecker> attrCertCheckers;
 		private int validityModel = PkixValidityModel;
 		private bool useDeltas = false;
 
@@ -90,10 +90,10 @@ namespace Org.BouncyCastle.Pkix
 			this.m_storesAttrCert = new List<IStore<X509V2AttributeCertificate>>();
 			this.m_storesCert = new List<IStore<X509Certificate>>();
 			this.m_storesCrl = new List<IStore<X509Crl>>();
-			this.trustedACIssuers = new HashSet();
-			this.necessaryACAttributes = new HashSet();
-			this.prohibitedACAttributes = new HashSet();
-			this.attrCertCheckers = new HashSet();
+			this.trustedACIssuers = new HashSet<TrustAnchor>();
+			this.necessaryACAttributes = new HashSet<string>();
+			this.prohibitedACAttributes = new HashSet<string>();
+			this.attrCertCheckers = new HashSet<PkixAttrCertChecker>();
 		}
 
 //		// TODO implement for other keystores (see Java build)?
@@ -501,10 +501,10 @@ namespace Org.BouncyCastle.Pkix
 			validityModel = parameters.validityModel;
 			useDeltas = parameters.useDeltas;
 			additionalLocationsEnabled = parameters.additionalLocationsEnabled;
-			trustedACIssuers = new HashSet(parameters.trustedACIssuers);
-			prohibitedACAttributes = new HashSet(parameters.prohibitedACAttributes);
-			necessaryACAttributes = new HashSet(parameters.necessaryACAttributes);
-			attrCertCheckers = new HashSet(parameters.attrCertCheckers);
+			trustedACIssuers = new HashSet<TrustAnchor>(parameters.trustedACIssuers);
+			prohibitedACAttributes = new HashSet<string>(parameters.prohibitedACAttributes);
+			necessaryACAttributes = new HashSet<string>(parameters.necessaryACAttributes);
+			attrCertCheckers = new HashSet<PkixAttrCertChecker>(parameters.attrCertCheckers);
 		}
 
 		/**
@@ -637,9 +637,9 @@ namespace Org.BouncyCastle.Pkix
 		*
 		* @return Returns an immutable set of the trusted AC issuers.
 		*/
-		public virtual ISet GetTrustedACIssuers()
+		public virtual ISet<TrustAnchor> GetTrustedACIssuers()
 		{
-			return new HashSet(trustedACIssuers);
+			return new HashSet<TrustAnchor>(trustedACIssuers);
 		}
 
 		/**
@@ -657,24 +657,15 @@ namespace Org.BouncyCastle.Pkix
 		* @throws ClassCastException if an element of <code>stores</code> is not
 		*             a <code>TrustAnchor</code>.
 		*/
-		public virtual void SetTrustedACIssuers(
-			ISet trustedACIssuers)
+		public virtual void SetTrustedACIssuers(ISet<TrustAnchor> trustedACIssuers)
 		{
 			if (trustedACIssuers == null)
 			{
-				this.trustedACIssuers = new HashSet();
+				this.trustedACIssuers = new HashSet<TrustAnchor>();
 			}
 			else
 			{
-				foreach (object obj in trustedACIssuers)
-				{
-					if (!(obj is TrustAnchor))
-					{
-						throw new InvalidCastException("All elements of set must be "
-							+ "of type " + typeof(TrustAnchor).FullName + ".");
-					}
-				}
-				this.trustedACIssuers = new HashSet(trustedACIssuers);
+				this.trustedACIssuers = new HashSet<TrustAnchor>(trustedACIssuers);
 			}
 		}
 
@@ -688,9 +679,9 @@ namespace Org.BouncyCastle.Pkix
 		*
 		* @return Returns the necessary AC attributes.
 		*/
-		public virtual ISet GetNecessaryACAttributes()
+		public virtual ISet<string> GetNecessaryACAttributes()
 		{
-			return new HashSet(necessaryACAttributes);
+			return new HashSet<string>(necessaryACAttributes);
 		}
 
 		/**
@@ -707,24 +698,15 @@ namespace Org.BouncyCastle.Pkix
 		*             <code>necessaryACAttributes</code> is not a
 		*             <code>String</code>.
 		*/
-		public virtual void SetNecessaryACAttributes(
-			ISet necessaryACAttributes)
+		public virtual void SetNecessaryACAttributes(ISet<string> necessaryACAttributes)
 		{
 			if (necessaryACAttributes == null)
 			{
-				this.necessaryACAttributes = new HashSet();
+				this.necessaryACAttributes = new HashSet<string>();
 			}
 			else
 			{
-				foreach (object obj in necessaryACAttributes)
-				{
-					if (!(obj is string))
-					{
-						throw new InvalidCastException("All elements of set must be "
-							+ "of type string.");
-					}
-				}
-				this.necessaryACAttributes = new HashSet(necessaryACAttributes);
+				this.necessaryACAttributes = new HashSet<string>(necessaryACAttributes);
 			}
 		}
 
@@ -737,9 +719,9 @@ namespace Org.BouncyCastle.Pkix
 		*
 		* @return Returns the prohibited AC attributes. Is never <code>null</code>.
 		*/
-		public virtual ISet GetProhibitedACAttributes()
+		public virtual ISet<string> GetProhibitedACAttributes()
 		{
-			return new HashSet(prohibitedACAttributes);
+			return new HashSet<string>(prohibitedACAttributes);
 		}
 
 		/**
@@ -756,21 +738,15 @@ namespace Org.BouncyCastle.Pkix
 		*             <code>prohibitedACAttributes</code> is not a
 		*             <code>String</code>.
 		*/
-		public virtual void SetProhibitedACAttributes(
-			ISet prohibitedACAttributes)
+		public virtual void SetProhibitedACAttributes(ISet<string> prohibitedACAttributes)
 		{
 			if (prohibitedACAttributes == null)
 			{
-				this.prohibitedACAttributes = new HashSet();
+				this.prohibitedACAttributes = new HashSet<string>();
 			}
 			else
 			{
-				foreach (object obj in prohibitedACAttributes)
-				{
-					if (!(obj is string))
-						throw new InvalidCastException("All elements of set must be of type string.");
-				}
-				this.prohibitedACAttributes = new HashSet(prohibitedACAttributes);
+				this.prohibitedACAttributes = new HashSet<string>(prohibitedACAttributes);
 			}
 		}
 
@@ -781,9 +757,9 @@ namespace Org.BouncyCastle.Pkix
 		* @return Returns the attribute certificate checker. Is never
 		*         <code>null</code>.
 		*/
-		public virtual ISet GetAttrCertCheckers()
+		public virtual ISet<PkixAttrCertChecker> GetAttrCertCheckers()
 		{
-			return new HashSet(attrCertCheckers);
+			return new HashSet<PkixAttrCertChecker>(attrCertCheckers);
 		}
 
 		/**
@@ -800,24 +776,15 @@ namespace Org.BouncyCastle.Pkix
 		* @throws ClassCastException if an element of <code>attrCertCheckers</code>
 		*             is not a <code>PKIXAttrCertChecker</code>.
 		*/
-		public virtual void SetAttrCertCheckers(
-			ISet attrCertCheckers)
+		public virtual void SetAttrCertCheckers(ISet<PkixAttrCertChecker> attrCertCheckers)
 		{
 			if (attrCertCheckers == null)
 			{
-				this.attrCertCheckers = new HashSet();
+				this.attrCertCheckers = new HashSet<PkixAttrCertChecker>();
 			}
 			else
 			{
-				foreach (object obj in attrCertCheckers)
-				{
-					if (!(obj is PkixAttrCertChecker))
-					{
-						throw new InvalidCastException("All elements of set must be "
-							+ "of type " + typeof(PkixAttrCertChecker).FullName + ".");
-					}
-				}
-				this.attrCertCheckers = new HashSet(attrCertCheckers);
+				this.attrCertCheckers = new HashSet<PkixAttrCertChecker>(attrCertCheckers);
 			}
 		}
 	}
diff --git a/crypto/src/pkix/Rfc3281CertPathUtilities.cs b/crypto/src/pkix/Rfc3281CertPathUtilities.cs
index 686498b3e..4d12ad0c0 100644
--- a/crypto/src/pkix/Rfc3281CertPathUtilities.cs
+++ b/crypto/src/pkix/Rfc3281CertPathUtilities.cs
@@ -1,5 +1,4 @@
 using System;
-using System.Collections;
 using System.Collections.Generic;
 
 using Org.BouncyCastle.Asn1.X509;
@@ -82,8 +81,8 @@ namespace Org.BouncyCastle.Pkix
             // check if revocation is available
             if (attrCert.GetExtensionValue(X509Extensions.NoRevAvail) != null)
             {
-                if (attrCert.GetExtensionValue(X509Extensions.CrlDistributionPoints) != null
-                    || attrCert.GetExtensionValue(X509Extensions.AuthorityInfoAccess) != null)
+                if (attrCert.GetExtensionValue(X509Extensions.CrlDistributionPoints) != null ||
+                    attrCert.GetExtensionValue(X509Extensions.AuthorityInfoAccess) != null)
                 {
                     throw new PkixCertPathValidatorException(
                         "No rev avail extension is set, but also an AC revocation pointer.");
@@ -92,22 +91,20 @@ namespace Org.BouncyCastle.Pkix
                 return;
             }
 
-            CrlDistPoint crldp = null;
+            CrlDistPoint crldp;
 			try
 			{
 				crldp = CrlDistPoint.GetInstance(
-					PkixCertPathValidatorUtilities.GetExtensionValue(
-						attrCert, X509Extensions.CrlDistributionPoints));
+					PkixCertPathValidatorUtilities.GetExtensionValue(attrCert, X509Extensions.CrlDistributionPoints));
 			}
 			catch (Exception e)
 			{
-				throw new PkixCertPathValidatorException(
-					"CRL distribution point extension could not be read.", e);
+				throw new PkixCertPathValidatorException("CRL distribution point extension could not be read.", e);
 			}
+
 			try
 			{
-				PkixCertPathValidatorUtilities
-					.AddAdditionalStoresFromCrlDistributionPoint(crldp, paramsPKIX);
+				PkixCertPathValidatorUtilities.AddAdditionalStoresFromCrlDistributionPoint(crldp, paramsPKIX);
 			}
 			catch (Exception e)
 			{
@@ -123,34 +120,30 @@ namespace Org.BouncyCastle.Pkix
 			// for each distribution point
 			if (crldp != null)
 			{
-				DistributionPoint[] dps = null;
+				DistributionPoint[] dps;
 				try
 				{
 					dps = crldp.GetDistributionPoints();
 				}
 				catch (Exception e)
 				{
-					throw new PkixCertPathValidatorException(
-						"Distribution points could not be read.", e);
+					throw new PkixCertPathValidatorException("Distribution points could not be read.", e);
 				}
 				try
 				{
-					for (int i = 0; i < dps.Length
-						&& certStatus.Status == CertStatus.Unrevoked
-						&& !reasonsMask.IsAllReasons; i++)
+					for (int i = 0;
+						i < dps.Length && certStatus.Status == CertStatus.Unrevoked && !reasonsMask.IsAllReasons;
+						i++)
 					{
-						PkixParameters paramsPKIXClone = (PkixParameters) paramsPKIX
-							.Clone();
-						CheckCrl(dps[i], attrCert, paramsPKIXClone,
-							validDate, issuerCert, certStatus, reasonsMask,
+						PkixParameters paramsPKIXClone = (PkixParameters)paramsPKIX.Clone();
+						CheckCrl(dps[i], attrCert, paramsPKIXClone,validDate, issuerCert, certStatus, reasonsMask,
 							certPathCerts);
 						validCrlFound = true;
 					}
 				}
 				catch (Exception e)
 				{
-					lastException = new Exception(
-						"No valid CRL for distribution point found.", e);
+					lastException = new Exception("No valid CRL for distribution point found.", e);
 				}
 			}
 
@@ -160,8 +153,7 @@ namespace Org.BouncyCastle.Pkix
 			* distribution point but issued by the certificate issuer.
 			*/
 
-			if (certStatus.Status == CertStatus.Unrevoked
-				&& !reasonsMask.IsAllReasons)
+			if (certStatus.Status == CertStatus.Unrevoked && !reasonsMask.IsAllReasons)
 			{
 				try
 				{
@@ -177,9 +169,7 @@ namespace Org.BouncyCastle.Pkix
                     }
                     catch (Exception e)
 					{
-						throw new Exception(
-							"Issuer from certificate for CRL could not be reencoded.",
-							e);
+						throw new Exception("Issuer from certificate for CRL could not be reencoded.", e);
 					}
 					DistributionPoint dp = new DistributionPoint(
 						new DistributionPointName(0, new GeneralNames(
@@ -191,24 +181,18 @@ namespace Org.BouncyCastle.Pkix
 				}
 				catch (Exception e)
 				{
-					lastException = new Exception(
-						"No valid CRL for distribution point found.", e);
+					lastException = new Exception("No valid CRL for distribution point found.", e);
 				}
 			}
 
 			if (!validCrlFound)
-			{
-				throw new PkixCertPathValidatorException(
-					"No valid CRL found.", lastException);
-			}
+				throw new PkixCertPathValidatorException("No valid CRL found.", lastException);
+
 			if (certStatus.Status != CertStatus.Unrevoked)
 			{
                 // This format is enforced by the NistCertPath tests
-                string formattedDate = certStatus.RevocationDate.Value.ToString(
-                    "ddd MMM dd HH:mm:ss K yyyy");
-                string message = "Attribute certificate revocation after "
-					+ formattedDate;
-				message += ", reason: "
+                string formattedDate = certStatus.RevocationDate.Value.ToString("ddd MMM dd HH:mm:ss K yyyy");
+                string message = "Attribute certificate revocation after " + formattedDate + ", reason: "
 					+ Rfc3280CertPathUtilities.CrlReasons[certStatus.Status];
 				throw new PkixCertPathValidatorException(message);
 			}
@@ -474,9 +458,7 @@ namespace Org.BouncyCastle.Pkix
 
 			DateTime currentDate = DateTime.UtcNow;
 			if (validDate.CompareTo(currentDate) > 0)
-			{
 				throw new Exception("Validation time is in future.");
-			}
 
 			// (a)
 			/*
@@ -485,11 +467,11 @@ namespace Org.BouncyCastle.Pkix
 			* CRLs must be enabled in the ExtendedPkixParameters and are in
 			* getAdditionalStore()
 			*/
-			ISet<X509Crl> crls = PkixCertPathValidatorUtilities.GetCompleteCrls(dp, attrCert, currentDate, paramsPKIX);
+			var crls = PkixCertPathValidatorUtilities.GetCompleteCrls(dp, attrCert, currentDate, paramsPKIX);
 			bool validCrlFound = false;
 			Exception lastException = null;
 
-			IEnumerator crl_iter = crls.GetEnumerator();
+			var crl_iter = crls.GetEnumerator();
 
 			while (crl_iter.MoveNext()
 				&& certStatus.Status == CertStatus.Unrevoked
@@ -497,7 +479,7 @@ namespace Org.BouncyCastle.Pkix
 			{
 				try
 				{
-					X509Crl crl = (X509Crl) crl_iter.Current;
+					X509Crl crl = crl_iter.Current;
 
 					// (d)
 					ReasonsMask interimReasonsMask = Rfc3280CertPathUtilities.ProcessCrlD(crl, dp);
@@ -509,13 +491,12 @@ namespace Org.BouncyCastle.Pkix
 					* must be ignored.
 					*/
 					if (!interimReasonsMask.HasNewReasons(reasonMask))
-					{
 						continue;
-					}
 
 					// (f)
-					var keys = Rfc3280CertPathUtilities.ProcessCrlF(crl, attrCert,
-						null, null, paramsPKIX, certPathCerts);
+					var keys = Rfc3280CertPathUtilities.ProcessCrlF(crl, attrCert,null, null, paramsPKIX,
+						certPathCerts);
+
 					// (g)
 					AsymmetricKeyParameter pubKey = Rfc3280CertPathUtilities.ProcessCrlG(crl, keys);
 
@@ -524,8 +505,8 @@ namespace Org.BouncyCastle.Pkix
 					if (paramsPKIX.IsUseDeltasEnabled)
 					{
 						// get delta CRLs
-						ISet<X509Crl> deltaCRLs = PkixCertPathValidatorUtilities.GetDeltaCrls(
-							currentDate, paramsPKIX, crl);
+						var deltaCRLs = PkixCertPathValidatorUtilities.GetDeltaCrls(currentDate, paramsPKIX, crl);
+
 						// we only want one valid delta CRL
 						// (h)
 						deltaCRL = Rfc3280CertPathUtilities.ProcessCrlH(deltaCRLs, pubKey);
@@ -551,10 +532,7 @@ namespace Org.BouncyCastle.Pkix
 						* first check is not done
 						*/
 						if (attrCert.NotAfter.CompareTo(crl.ThisUpdate) < 0)
-						{
-							throw new Exception(
-								"No valid CRL for current time found.");
-						}
+							throw new Exception("No valid CRL for current time found.");
 					}
 
 					Rfc3280CertPathUtilities.ProcessCrlB1(dp, attrCert, crl);
@@ -588,10 +566,9 @@ namespace Org.BouncyCastle.Pkix
 					lastException = e;
 				}
 			}
+
 			if (!validCrlFound)
-			{
 				throw lastException;
-			}
 		}
 	}
 }
diff --git a/crypto/src/security/AgreementUtilities.cs b/crypto/src/security/AgreementUtilities.cs
index 26d1628cc..0b7fc2a2b 100644
--- a/crypto/src/security/AgreementUtilities.cs
+++ b/crypto/src/security/AgreementUtilities.cs
@@ -1,4 +1,5 @@
-using System.Collections;
+using System;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.EdEC;
@@ -7,30 +8,26 @@ using Org.BouncyCastle.Crypto;
 using Org.BouncyCastle.Crypto.Agreement;
 using Org.BouncyCastle.Crypto.Agreement.Kdf;
 using Org.BouncyCastle.Crypto.Digests;
-using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Collections;
 
 namespace Org.BouncyCastle.Security
 {
 	/// <remarks>
 	///  Utility class for creating IBasicAgreement objects from their names/Oids
 	/// </remarks>
-	public sealed class AgreementUtilities
+	public static class AgreementUtilities
 	{
-		private AgreementUtilities()
-		{
-		}
-
-		private static readonly IDictionary algorithms = Platform.CreateHashtable();
-        //private static readonly IDictionary oids = Platform.CreateHashtable();
+		private static readonly IDictionary<string, string> Algorithms =
+			new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
 
         static AgreementUtilities()
 		{
-            algorithms[X9ObjectIdentifiers.DHSinglePassCofactorDHSha1KdfScheme.Id] = "ECCDHWITHSHA1KDF";
-			algorithms[X9ObjectIdentifiers.DHSinglePassStdDHSha1KdfScheme.Id] = "ECDHWITHSHA1KDF";
-			algorithms[X9ObjectIdentifiers.MqvSinglePassSha1KdfScheme.Id] = "ECMQVWITHSHA1KDF";
+            Algorithms[X9ObjectIdentifiers.DHSinglePassCofactorDHSha1KdfScheme.Id] = "ECCDHWITHSHA1KDF";
+			Algorithms[X9ObjectIdentifiers.DHSinglePassStdDHSha1KdfScheme.Id] = "ECDHWITHSHA1KDF";
+			Algorithms[X9ObjectIdentifiers.MqvSinglePassSha1KdfScheme.Id] = "ECMQVWITHSHA1KDF";
 
-            algorithms[EdECObjectIdentifiers.id_X25519.Id] = "X25519";
-            algorithms[EdECObjectIdentifiers.id_X448.Id] = "X448";
+            Algorithms[EdECObjectIdentifiers.id_X25519.Id] = "X25519";
+            Algorithms[EdECObjectIdentifiers.id_X448.Id] = "X448";
         }
 
         public static IBasicAgreement GetBasicAgreement(
@@ -94,8 +91,7 @@ namespace Org.BouncyCastle.Security
             return GetRawAgreement(oid.Id);
         }
 
-        public static IRawAgreement GetRawAgreement(
-            string algorithm)
+        public static IRawAgreement GetRawAgreement(string algorithm)
         {
             string mechanism = GetMechanism(algorithm);
 
@@ -108,17 +104,16 @@ namespace Org.BouncyCastle.Security
             throw new SecurityUtilityException("Raw Agreement " + algorithm + " not recognised.");
         }
 
-		public static string GetAlgorithmName(
-			DerObjectIdentifier oid)
+		public static string GetAlgorithmName(DerObjectIdentifier oid)
 		{
-			return (string)algorithms[oid.Id];
+			return CollectionUtilities.GetValueOrNull(Algorithms, oid.Id);
 		}
 
-        private static string GetMechanism(string algorithm)
+		private static string GetMechanism(string algorithm)
         {
-            string upper = Platform.ToUpperInvariant(algorithm);
-            string mechanism = (string)algorithms[upper];
-            return mechanism == null ? upper : mechanism;
+			var mechanism = CollectionUtilities.GetValueOrKey(Algorithms, algorithm);
+
+			return mechanism.ToUpperInvariant();
         }
 	}
 }
diff --git a/crypto/src/security/CipherUtilities.cs b/crypto/src/security/CipherUtilities.cs
index 3b92add00..a6849c102 100644
--- a/crypto/src/security/CipherUtilities.cs
+++ b/crypto/src/security/CipherUtilities.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.CryptoPro;
@@ -19,13 +19,14 @@ using Org.BouncyCastle.Crypto.Macs;
 using Org.BouncyCastle.Crypto.Modes;
 using Org.BouncyCastle.Crypto.Paddings;
 using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Collections;
 
 namespace Org.BouncyCastle.Security
 {
     /// <remarks>
     ///  Cipher Utility class contains methods that can not be specifically grouped into other classes.
     /// </remarks>
-    public sealed class CipherUtilities
+    public static class CipherUtilities
     {
         private enum CipherAlgorithm {
             AES,
@@ -111,8 +112,8 @@ namespace Org.BouncyCastle.Security
             ZEROBYTEPADDING,
         };
 
-        private static readonly IDictionary algorithms = Platform.CreateHashtable();
-        private static readonly IDictionary oids = Platform.CreateHashtable();
+        private static readonly Dictionary<string, string> Algorithms =
+            new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
 
         static CipherUtilities()
         {
@@ -123,172 +124,142 @@ namespace Org.BouncyCastle.Security
 
             // TODO Flesh out the list of aliases
 
-            algorithms[NistObjectIdentifiers.IdAes128Cbc.Id] = "AES/CBC/PKCS7PADDING";
-            algorithms[NistObjectIdentifiers.IdAes192Cbc.Id] = "AES/CBC/PKCS7PADDING";
-            algorithms[NistObjectIdentifiers.IdAes256Cbc.Id] = "AES/CBC/PKCS7PADDING";
-
-            algorithms[NistObjectIdentifiers.IdAes128Ccm.Id] = "AES/CCM/NOPADDING";
-            algorithms[NistObjectIdentifiers.IdAes192Ccm.Id] = "AES/CCM/NOPADDING";
-            algorithms[NistObjectIdentifiers.IdAes256Ccm.Id] = "AES/CCM/NOPADDING";
-
-            algorithms[NistObjectIdentifiers.IdAes128Cfb.Id] = "AES/CFB/NOPADDING";
-            algorithms[NistObjectIdentifiers.IdAes192Cfb.Id] = "AES/CFB/NOPADDING";
-            algorithms[NistObjectIdentifiers.IdAes256Cfb.Id] = "AES/CFB/NOPADDING";
-
-            algorithms[NistObjectIdentifiers.IdAes128Ecb.Id] = "AES/ECB/PKCS7PADDING";
-            algorithms[NistObjectIdentifiers.IdAes192Ecb.Id] = "AES/ECB/PKCS7PADDING";
-            algorithms[NistObjectIdentifiers.IdAes256Ecb.Id] = "AES/ECB/PKCS7PADDING";
-            algorithms["AES//PKCS7"] = "AES/ECB/PKCS7PADDING";
-            algorithms["AES//PKCS7PADDING"] = "AES/ECB/PKCS7PADDING";
-            algorithms["AES//PKCS5"] = "AES/ECB/PKCS7PADDING";
-            algorithms["AES//PKCS5PADDING"] = "AES/ECB/PKCS7PADDING";
+            Algorithms[NistObjectIdentifiers.IdAes128Cbc.Id] = "AES/CBC/PKCS7PADDING";
+            Algorithms[NistObjectIdentifiers.IdAes192Cbc.Id] = "AES/CBC/PKCS7PADDING";
+            Algorithms[NistObjectIdentifiers.IdAes256Cbc.Id] = "AES/CBC/PKCS7PADDING";
+
+            Algorithms[NistObjectIdentifiers.IdAes128Ccm.Id] = "AES/CCM/NOPADDING";
+            Algorithms[NistObjectIdentifiers.IdAes192Ccm.Id] = "AES/CCM/NOPADDING";
+            Algorithms[NistObjectIdentifiers.IdAes256Ccm.Id] = "AES/CCM/NOPADDING";
+
+            Algorithms[NistObjectIdentifiers.IdAes128Cfb.Id] = "AES/CFB/NOPADDING";
+            Algorithms[NistObjectIdentifiers.IdAes192Cfb.Id] = "AES/CFB/NOPADDING";
+            Algorithms[NistObjectIdentifiers.IdAes256Cfb.Id] = "AES/CFB/NOPADDING";
+
+            Algorithms[NistObjectIdentifiers.IdAes128Ecb.Id] = "AES/ECB/PKCS7PADDING";
+            Algorithms[NistObjectIdentifiers.IdAes192Ecb.Id] = "AES/ECB/PKCS7PADDING";
+            Algorithms[NistObjectIdentifiers.IdAes256Ecb.Id] = "AES/ECB/PKCS7PADDING";
+            Algorithms["AES//PKCS7"] = "AES/ECB/PKCS7PADDING";
+            Algorithms["AES//PKCS7PADDING"] = "AES/ECB/PKCS7PADDING";
+            Algorithms["AES//PKCS5"] = "AES/ECB/PKCS7PADDING";
+            Algorithms["AES//PKCS5PADDING"] = "AES/ECB/PKCS7PADDING";
 
-            algorithms[NistObjectIdentifiers.IdAes128Gcm.Id] = "AES/GCM/NOPADDING";
-            algorithms[NistObjectIdentifiers.IdAes192Gcm.Id] = "AES/GCM/NOPADDING";
-            algorithms[NistObjectIdentifiers.IdAes256Gcm.Id] = "AES/GCM/NOPADDING";
+            Algorithms[NistObjectIdentifiers.IdAes128Gcm.Id] = "AES/GCM/NOPADDING";
+            Algorithms[NistObjectIdentifiers.IdAes192Gcm.Id] = "AES/GCM/NOPADDING";
+            Algorithms[NistObjectIdentifiers.IdAes256Gcm.Id] = "AES/GCM/NOPADDING";
 
-            algorithms[NistObjectIdentifiers.IdAes128Ofb.Id] = "AES/OFB/NOPADDING";
-            algorithms[NistObjectIdentifiers.IdAes192Ofb.Id] = "AES/OFB/NOPADDING";
-            algorithms[NistObjectIdentifiers.IdAes256Ofb.Id] = "AES/OFB/NOPADDING";
+            Algorithms[NistObjectIdentifiers.IdAes128Ofb.Id] = "AES/OFB/NOPADDING";
+            Algorithms[NistObjectIdentifiers.IdAes192Ofb.Id] = "AES/OFB/NOPADDING";
+            Algorithms[NistObjectIdentifiers.IdAes256Ofb.Id] = "AES/OFB/NOPADDING";
 
-            algorithms[NsriObjectIdentifiers.id_aria128_cbc.Id] = "ARIA/CBC/PKCS7PADDING";
-            algorithms[NsriObjectIdentifiers.id_aria192_cbc.Id] = "ARIA/CBC/PKCS7PADDING";
-            algorithms[NsriObjectIdentifiers.id_aria256_cbc.Id] = "ARIA/CBC/PKCS7PADDING";
+            Algorithms[NsriObjectIdentifiers.id_aria128_cbc.Id] = "ARIA/CBC/PKCS7PADDING";
+            Algorithms[NsriObjectIdentifiers.id_aria192_cbc.Id] = "ARIA/CBC/PKCS7PADDING";
+            Algorithms[NsriObjectIdentifiers.id_aria256_cbc.Id] = "ARIA/CBC/PKCS7PADDING";
 
-            algorithms[NsriObjectIdentifiers.id_aria128_ccm.Id] = "ARIA/CCM/NOPADDING";
-            algorithms[NsriObjectIdentifiers.id_aria192_ccm.Id] = "ARIA/CCM/NOPADDING";
-            algorithms[NsriObjectIdentifiers.id_aria256_ccm.Id] = "ARIA/CCM/NOPADDING";
+            Algorithms[NsriObjectIdentifiers.id_aria128_ccm.Id] = "ARIA/CCM/NOPADDING";
+            Algorithms[NsriObjectIdentifiers.id_aria192_ccm.Id] = "ARIA/CCM/NOPADDING";
+            Algorithms[NsriObjectIdentifiers.id_aria256_ccm.Id] = "ARIA/CCM/NOPADDING";
 
-            algorithms[NsriObjectIdentifiers.id_aria128_cfb.Id] = "ARIA/CFB/NOPADDING";
-            algorithms[NsriObjectIdentifiers.id_aria192_cfb.Id] = "ARIA/CFB/NOPADDING";
-            algorithms[NsriObjectIdentifiers.id_aria256_cfb.Id] = "ARIA/CFB/NOPADDING";
+            Algorithms[NsriObjectIdentifiers.id_aria128_cfb.Id] = "ARIA/CFB/NOPADDING";
+            Algorithms[NsriObjectIdentifiers.id_aria192_cfb.Id] = "ARIA/CFB/NOPADDING";
+            Algorithms[NsriObjectIdentifiers.id_aria256_cfb.Id] = "ARIA/CFB/NOPADDING";
 
-            algorithms[NsriObjectIdentifiers.id_aria128_ctr.Id] = "ARIA/CTR/NOPADDING";
-            algorithms[NsriObjectIdentifiers.id_aria192_ctr.Id] = "ARIA/CTR/NOPADDING";
-            algorithms[NsriObjectIdentifiers.id_aria256_ctr.Id] = "ARIA/CTR/NOPADDING";
+            Algorithms[NsriObjectIdentifiers.id_aria128_ctr.Id] = "ARIA/CTR/NOPADDING";
+            Algorithms[NsriObjectIdentifiers.id_aria192_ctr.Id] = "ARIA/CTR/NOPADDING";
+            Algorithms[NsriObjectIdentifiers.id_aria256_ctr.Id] = "ARIA/CTR/NOPADDING";
 
-            algorithms[NsriObjectIdentifiers.id_aria128_ecb.Id] = "ARIA/ECB/PKCS7PADDING";
-            algorithms[NsriObjectIdentifiers.id_aria192_ecb.Id] = "ARIA/ECB/PKCS7PADDING";
-            algorithms[NsriObjectIdentifiers.id_aria256_ecb.Id] = "ARIA/ECB/PKCS7PADDING";
-            algorithms["ARIA//PKCS7"] = "ARIA/ECB/PKCS7PADDING";
-            algorithms["ARIA//PKCS7PADDING"] = "ARIA/ECB/PKCS7PADDING";
-            algorithms["ARIA//PKCS5"] = "ARIA/ECB/PKCS7PADDING";
-            algorithms["ARIA//PKCS5PADDING"] = "ARIA/ECB/PKCS7PADDING";
+            Algorithms[NsriObjectIdentifiers.id_aria128_ecb.Id] = "ARIA/ECB/PKCS7PADDING";
+            Algorithms[NsriObjectIdentifiers.id_aria192_ecb.Id] = "ARIA/ECB/PKCS7PADDING";
+            Algorithms[NsriObjectIdentifiers.id_aria256_ecb.Id] = "ARIA/ECB/PKCS7PADDING";
+            Algorithms["ARIA//PKCS7"] = "ARIA/ECB/PKCS7PADDING";
+            Algorithms["ARIA//PKCS7PADDING"] = "ARIA/ECB/PKCS7PADDING";
+            Algorithms["ARIA//PKCS5"] = "ARIA/ECB/PKCS7PADDING";
+            Algorithms["ARIA//PKCS5PADDING"] = "ARIA/ECB/PKCS7PADDING";
 
-            algorithms[NsriObjectIdentifiers.id_aria128_gcm.Id] = "ARIA/GCM/NOPADDING";
-            algorithms[NsriObjectIdentifiers.id_aria192_gcm.Id] = "ARIA/GCM/NOPADDING";
-            algorithms[NsriObjectIdentifiers.id_aria256_gcm.Id] = "ARIA/GCM/NOPADDING";
+            Algorithms[NsriObjectIdentifiers.id_aria128_gcm.Id] = "ARIA/GCM/NOPADDING";
+            Algorithms[NsriObjectIdentifiers.id_aria192_gcm.Id] = "ARIA/GCM/NOPADDING";
+            Algorithms[NsriObjectIdentifiers.id_aria256_gcm.Id] = "ARIA/GCM/NOPADDING";
 
-            algorithms[NsriObjectIdentifiers.id_aria128_ofb.Id] = "ARIA/OFB/NOPADDING";
-            algorithms[NsriObjectIdentifiers.id_aria192_ofb.Id] = "ARIA/OFB/NOPADDING";
-            algorithms[NsriObjectIdentifiers.id_aria256_ofb.Id] = "ARIA/OFB/NOPADDING";
+            Algorithms[NsriObjectIdentifiers.id_aria128_ofb.Id] = "ARIA/OFB/NOPADDING";
+            Algorithms[NsriObjectIdentifiers.id_aria192_ofb.Id] = "ARIA/OFB/NOPADDING";
+            Algorithms[NsriObjectIdentifiers.id_aria256_ofb.Id] = "ARIA/OFB/NOPADDING";
 
-            algorithms["RSA/ECB/PKCS1"] = "RSA//PKCS1PADDING";
-            algorithms["RSA/ECB/PKCS1PADDING"] = "RSA//PKCS1PADDING";
-            algorithms[PkcsObjectIdentifiers.RsaEncryption.Id] = "RSA//PKCS1PADDING";
-            algorithms[PkcsObjectIdentifiers.IdRsaesOaep.Id] = "RSA//OAEPPADDING";
+            Algorithms["RSA/ECB/PKCS1"] = "RSA//PKCS1PADDING";
+            Algorithms["RSA/ECB/PKCS1PADDING"] = "RSA//PKCS1PADDING";
+            Algorithms[PkcsObjectIdentifiers.RsaEncryption.Id] = "RSA//PKCS1PADDING";
+            Algorithms[PkcsObjectIdentifiers.IdRsaesOaep.Id] = "RSA//OAEPPADDING";
 
-            algorithms[OiwObjectIdentifiers.DesCbc.Id] = "DES/CBC";
-            algorithms[OiwObjectIdentifiers.DesCfb.Id] = "DES/CFB";
-            algorithms[OiwObjectIdentifiers.DesEcb.Id] = "DES/ECB";
-            algorithms[OiwObjectIdentifiers.DesOfb.Id] = "DES/OFB";
-            algorithms[OiwObjectIdentifiers.DesEde.Id] = "DESEDE";
-            algorithms["TDEA"] = "DESEDE";
-            algorithms[PkcsObjectIdentifiers.DesEde3Cbc.Id] = "DESEDE/CBC";
-            algorithms[PkcsObjectIdentifiers.RC2Cbc.Id] = "RC2/CBC";
-            algorithms["1.3.6.1.4.1.188.7.1.1.2"] = "IDEA/CBC";
-            algorithms["1.2.840.113533.7.66.10"] = "CAST5/CBC";
+            Algorithms[OiwObjectIdentifiers.DesCbc.Id] = "DES/CBC";
+            Algorithms[OiwObjectIdentifiers.DesCfb.Id] = "DES/CFB";
+            Algorithms[OiwObjectIdentifiers.DesEcb.Id] = "DES/ECB";
+            Algorithms[OiwObjectIdentifiers.DesOfb.Id] = "DES/OFB";
+            Algorithms[OiwObjectIdentifiers.DesEde.Id] = "DESEDE";
+            Algorithms["TDEA"] = "DESEDE";
+            Algorithms[PkcsObjectIdentifiers.DesEde3Cbc.Id] = "DESEDE/CBC";
+            Algorithms[PkcsObjectIdentifiers.RC2Cbc.Id] = "RC2/CBC";
+            Algorithms["1.3.6.1.4.1.188.7.1.1.2"] = "IDEA/CBC";
+            Algorithms["1.2.840.113533.7.66.10"] = "CAST5/CBC";
 
-            algorithms["RC4"] = "ARC4";
-            algorithms["ARCFOUR"] = "ARC4";
-            algorithms["1.2.840.113549.3.4"] = "ARC4";
+            Algorithms["RC4"] = "ARC4";
+            Algorithms["ARCFOUR"] = "ARC4";
+            Algorithms["1.2.840.113549.3.4"] = "ARC4";
 
 
 
-            algorithms["PBEWITHSHA1AND128BITRC4"] = "PBEWITHSHAAND128BITRC4";
-            algorithms[PkcsObjectIdentifiers.PbeWithShaAnd128BitRC4.Id] = "PBEWITHSHAAND128BITRC4";
-            algorithms["PBEWITHSHA1AND40BITRC4"] = "PBEWITHSHAAND40BITRC4";
-            algorithms[PkcsObjectIdentifiers.PbeWithShaAnd40BitRC4.Id] = "PBEWITHSHAAND40BITRC4";
+            Algorithms["PBEWITHSHA1AND128BITRC4"] = "PBEWITHSHAAND128BITRC4";
+            Algorithms[PkcsObjectIdentifiers.PbeWithShaAnd128BitRC4.Id] = "PBEWITHSHAAND128BITRC4";
+            Algorithms["PBEWITHSHA1AND40BITRC4"] = "PBEWITHSHAAND40BITRC4";
+            Algorithms[PkcsObjectIdentifiers.PbeWithShaAnd40BitRC4.Id] = "PBEWITHSHAAND40BITRC4";
 
-            algorithms["PBEWITHSHA1ANDDES"] = "PBEWITHSHA1ANDDES-CBC";
-            algorithms[PkcsObjectIdentifiers.PbeWithSha1AndDesCbc.Id] = "PBEWITHSHA1ANDDES-CBC";
-            algorithms["PBEWITHSHA1ANDRC2"] = "PBEWITHSHA1ANDRC2-CBC";
-            algorithms[PkcsObjectIdentifiers.PbeWithSha1AndRC2Cbc.Id] = "PBEWITHSHA1ANDRC2-CBC";
+            Algorithms["PBEWITHSHA1ANDDES"] = "PBEWITHSHA1ANDDES-CBC";
+            Algorithms[PkcsObjectIdentifiers.PbeWithSha1AndDesCbc.Id] = "PBEWITHSHA1ANDDES-CBC";
+            Algorithms["PBEWITHSHA1ANDRC2"] = "PBEWITHSHA1ANDRC2-CBC";
+            Algorithms[PkcsObjectIdentifiers.PbeWithSha1AndRC2Cbc.Id] = "PBEWITHSHA1ANDRC2-CBC";
 
-            algorithms["PBEWITHSHA1AND3-KEYTRIPLEDES-CBC"] = "PBEWITHSHAAND3-KEYTRIPLEDES-CBC";
-            algorithms["PBEWITHSHAAND3KEYTRIPLEDES"] = "PBEWITHSHAAND3-KEYTRIPLEDES-CBC";
-            algorithms[PkcsObjectIdentifiers.PbeWithShaAnd3KeyTripleDesCbc.Id] = "PBEWITHSHAAND3-KEYTRIPLEDES-CBC";
-            algorithms["PBEWITHSHA1ANDDESEDE"] = "PBEWITHSHAAND3-KEYTRIPLEDES-CBC";
+            Algorithms["PBEWITHSHA1AND3-KEYTRIPLEDES-CBC"] = "PBEWITHSHAAND3-KEYTRIPLEDES-CBC";
+            Algorithms["PBEWITHSHAAND3KEYTRIPLEDES"] = "PBEWITHSHAAND3-KEYTRIPLEDES-CBC";
+            Algorithms[PkcsObjectIdentifiers.PbeWithShaAnd3KeyTripleDesCbc.Id] = "PBEWITHSHAAND3-KEYTRIPLEDES-CBC";
+            Algorithms["PBEWITHSHA1ANDDESEDE"] = "PBEWITHSHAAND3-KEYTRIPLEDES-CBC";
 
-            algorithms["PBEWITHSHA1AND2-KEYTRIPLEDES-CBC"] = "PBEWITHSHAAND2-KEYTRIPLEDES-CBC";
-            algorithms[PkcsObjectIdentifiers.PbeWithShaAnd2KeyTripleDesCbc.Id] = "PBEWITHSHAAND2-KEYTRIPLEDES-CBC";
+            Algorithms["PBEWITHSHA1AND2-KEYTRIPLEDES-CBC"] = "PBEWITHSHAAND2-KEYTRIPLEDES-CBC";
+            Algorithms[PkcsObjectIdentifiers.PbeWithShaAnd2KeyTripleDesCbc.Id] = "PBEWITHSHAAND2-KEYTRIPLEDES-CBC";
 
-            algorithms["PBEWITHSHA1AND128BITRC2-CBC"] = "PBEWITHSHAAND128BITRC2-CBC";
-            algorithms[PkcsObjectIdentifiers.PbeWithShaAnd128BitRC2Cbc.Id] = "PBEWITHSHAAND128BITRC2-CBC";
+            Algorithms["PBEWITHSHA1AND128BITRC2-CBC"] = "PBEWITHSHAAND128BITRC2-CBC";
+            Algorithms[PkcsObjectIdentifiers.PbeWithShaAnd128BitRC2Cbc.Id] = "PBEWITHSHAAND128BITRC2-CBC";
 
-            algorithms["PBEWITHSHA1AND40BITRC2-CBC"] = "PBEWITHSHAAND40BITRC2-CBC";
-            algorithms[PkcsObjectIdentifiers.PbewithShaAnd40BitRC2Cbc.Id] = "PBEWITHSHAAND40BITRC2-CBC";
+            Algorithms["PBEWITHSHA1AND40BITRC2-CBC"] = "PBEWITHSHAAND40BITRC2-CBC";
+            Algorithms[PkcsObjectIdentifiers.PbewithShaAnd40BitRC2Cbc.Id] = "PBEWITHSHAAND40BITRC2-CBC";
 
-            algorithms["PBEWITHSHA1AND128BITAES-CBC-BC"] = "PBEWITHSHAAND128BITAES-CBC-BC";
-            algorithms["PBEWITHSHA-1AND128BITAES-CBC-BC"] = "PBEWITHSHAAND128BITAES-CBC-BC";
+            Algorithms["PBEWITHSHA1AND128BITAES-CBC-BC"] = "PBEWITHSHAAND128BITAES-CBC-BC";
+            Algorithms["PBEWITHSHA-1AND128BITAES-CBC-BC"] = "PBEWITHSHAAND128BITAES-CBC-BC";
 
-            algorithms["PBEWITHSHA1AND192BITAES-CBC-BC"] = "PBEWITHSHAAND192BITAES-CBC-BC";
-            algorithms["PBEWITHSHA-1AND192BITAES-CBC-BC"] = "PBEWITHSHAAND192BITAES-CBC-BC";
+            Algorithms["PBEWITHSHA1AND192BITAES-CBC-BC"] = "PBEWITHSHAAND192BITAES-CBC-BC";
+            Algorithms["PBEWITHSHA-1AND192BITAES-CBC-BC"] = "PBEWITHSHAAND192BITAES-CBC-BC";
 
-            algorithms["PBEWITHSHA1AND256BITAES-CBC-BC"] = "PBEWITHSHAAND256BITAES-CBC-BC";
-            algorithms["PBEWITHSHA-1AND256BITAES-CBC-BC"] = "PBEWITHSHAAND256BITAES-CBC-BC";
+            Algorithms["PBEWITHSHA1AND256BITAES-CBC-BC"] = "PBEWITHSHAAND256BITAES-CBC-BC";
+            Algorithms["PBEWITHSHA-1AND256BITAES-CBC-BC"] = "PBEWITHSHAAND256BITAES-CBC-BC";
 
-            algorithms["PBEWITHSHA-256AND128BITAES-CBC-BC"] = "PBEWITHSHA256AND128BITAES-CBC-BC";
-            algorithms["PBEWITHSHA-256AND192BITAES-CBC-BC"] = "PBEWITHSHA256AND192BITAES-CBC-BC";
-            algorithms["PBEWITHSHA-256AND256BITAES-CBC-BC"] = "PBEWITHSHA256AND256BITAES-CBC-BC";
+            Algorithms["PBEWITHSHA-256AND128BITAES-CBC-BC"] = "PBEWITHSHA256AND128BITAES-CBC-BC";
+            Algorithms["PBEWITHSHA-256AND192BITAES-CBC-BC"] = "PBEWITHSHA256AND192BITAES-CBC-BC";
+            Algorithms["PBEWITHSHA-256AND256BITAES-CBC-BC"] = "PBEWITHSHA256AND256BITAES-CBC-BC";
 
 
-            algorithms["GOST"] = "GOST28147";
-            algorithms["GOST-28147"] = "GOST28147";
-            algorithms[CryptoProObjectIdentifiers.GostR28147Cbc.Id] = "GOST28147/CBC/PKCS7PADDING";
+            Algorithms["GOST"] = "GOST28147";
+            Algorithms["GOST-28147"] = "GOST28147";
+            Algorithms[CryptoProObjectIdentifiers.GostR28147Cbc.Id] = "GOST28147/CBC/PKCS7PADDING";
 
-            algorithms["RC5-32"] = "RC5";
+            Algorithms["RC5-32"] = "RC5";
 
-            algorithms[NttObjectIdentifiers.IdCamellia128Cbc.Id] = "CAMELLIA/CBC/PKCS7PADDING";
-            algorithms[NttObjectIdentifiers.IdCamellia192Cbc.Id] = "CAMELLIA/CBC/PKCS7PADDING";
-            algorithms[NttObjectIdentifiers.IdCamellia256Cbc.Id] = "CAMELLIA/CBC/PKCS7PADDING";
+            Algorithms[NttObjectIdentifiers.IdCamellia128Cbc.Id] = "CAMELLIA/CBC/PKCS7PADDING";
+            Algorithms[NttObjectIdentifiers.IdCamellia192Cbc.Id] = "CAMELLIA/CBC/PKCS7PADDING";
+            Algorithms[NttObjectIdentifiers.IdCamellia256Cbc.Id] = "CAMELLIA/CBC/PKCS7PADDING";
 
-            algorithms[KisaObjectIdentifiers.IdSeedCbc.Id] = "SEED/CBC/PKCS7PADDING";
+            Algorithms[KisaObjectIdentifiers.IdSeedCbc.Id] = "SEED/CBC/PKCS7PADDING";
 
-            algorithms["1.3.6.1.4.1.3029.1.2"] = "BLOWFISH/CBC";
+            Algorithms["1.3.6.1.4.1.3029.1.2"] = "BLOWFISH/CBC";
 
-            algorithms["CHACHA20"] = "CHACHA7539";
-            algorithms[PkcsObjectIdentifiers.IdAlgAeadChaCha20Poly1305.Id] = "CHACHA20-POLY1305";
-        }
-
-        private CipherUtilities()
-        {
-        }
-
-        /// <summary>
-        /// Returns a ObjectIdentifier for a give encoding.
-        /// </summary>
-        /// <param name="mechanism">A string representation of the encoding.</param>
-        /// <returns>A DerObjectIdentifier, null if the Oid is not available.</returns>
-        // TODO Don't really want to support this
-        public static DerObjectIdentifier GetObjectIdentifier(
-            string mechanism)
-        {
-            if (mechanism == null)
-                throw new ArgumentNullException("mechanism");
-
-            mechanism = Platform.ToUpperInvariant(mechanism);
-            string aliased = (string) algorithms[mechanism];
-
-            if (aliased != null)
-                mechanism = aliased;
-
-            return (DerObjectIdentifier) oids[mechanism];
-        }
-
-        public static ICollection Algorithms
-        {
-            get { return oids.Keys; }
+            Algorithms["CHACHA20"] = "CHACHA7539";
+            Algorithms[PkcsObjectIdentifiers.IdAlgAeadChaCha20Poly1305.Id] = "CHACHA20-POLY1305";
         }
 
         public static IBufferedCipher GetCipher(
@@ -297,20 +268,12 @@ namespace Org.BouncyCastle.Security
             return GetCipher(oid.Id);
         }
 
-        public static IBufferedCipher GetCipher(
-            string algorithm)
+        public static IBufferedCipher GetCipher(string algorithm)
         {
             if (algorithm == null)
-                throw new ArgumentNullException("algorithm");
+                throw new ArgumentNullException(nameof(algorithm));
 
-            algorithm = Platform.ToUpperInvariant(algorithm);
-
-            {
-                string aliased = (string) algorithms[algorithm];
-
-                if (aliased != null)
-                    algorithm = aliased;
-            }
+            algorithm = CollectionUtilities.GetValueOrKey(Algorithms, algorithm).ToUpperInvariant();
 
             IBasicAgreement iesAgreement = null;
             if (algorithm == "IES")
@@ -390,14 +353,7 @@ namespace Org.BouncyCastle.Security
             IAsymmetricBlockCipher asymBlockCipher = null;
             IStreamCipher streamCipher = null;
 
-            string algorithmName = parts[0];
-
-            {
-                string aliased = (string)algorithms[algorithmName];
-
-                if (aliased != null)
-                    algorithmName = aliased;
-            }
+            string algorithmName = CollectionUtilities.GetValueOrKey(Algorithms, parts[0]).ToUpperInvariant();
 
             CipherAlgorithm cipherAlgorithm;
             try
@@ -411,126 +367,126 @@ namespace Org.BouncyCastle.Security
 
             switch (cipherAlgorithm)
             {
-                case CipherAlgorithm.AES:
-                    blockCipher = new AesEngine();
-                    break;
-                case CipherAlgorithm.ARC4:
-                    streamCipher = new RC4Engine();
-                    break;
-                case CipherAlgorithm.ARIA:
-                    blockCipher = new AriaEngine();
-                    break;
-                case CipherAlgorithm.BLOWFISH:
-                    blockCipher = new BlowfishEngine();
-                    break;
-                case CipherAlgorithm.CAMELLIA:
-                    blockCipher = new CamelliaEngine();
-                    break;
-                case CipherAlgorithm.CAST5:
-                    blockCipher = new Cast5Engine();
-                    break;
-                case CipherAlgorithm.CAST6:
-                    blockCipher = new Cast6Engine();
-                    break;
-                case CipherAlgorithm.CHACHA:
-                    streamCipher = new ChaChaEngine();
-                    break;
-                case CipherAlgorithm.CHACHA20_POLY1305:
-                    aeadCipher = new ChaCha20Poly1305();
-                    break;
-                case CipherAlgorithm.CHACHA7539:
-                    streamCipher = new ChaCha7539Engine();
-                    break;
-                case CipherAlgorithm.DES:
-                    blockCipher = new DesEngine();
-                    break;
-                case CipherAlgorithm.DESEDE:
-                    blockCipher = new DesEdeEngine();
-                    break;
-                case CipherAlgorithm.ELGAMAL:
-                    asymBlockCipher = new ElGamalEngine();
-                    break;
-                case CipherAlgorithm.GOST28147:
-                    blockCipher = new Gost28147Engine();
-                    break;
-                case CipherAlgorithm.HC128:
-                    streamCipher = new HC128Engine();
-                    break;
-                case CipherAlgorithm.HC256:
-                    streamCipher = new HC256Engine();
-                    break;
-                case CipherAlgorithm.IDEA:
-                    blockCipher = new IdeaEngine();
-                    break;
-                case CipherAlgorithm.NOEKEON:
-                    blockCipher = new NoekeonEngine();
-                    break;
-                case CipherAlgorithm.PBEWITHSHAAND128BITRC4:
-                case CipherAlgorithm.PBEWITHSHAAND40BITRC4:
-                    streamCipher = new RC4Engine();
-                    break;
-                case CipherAlgorithm.RC2:
-                    blockCipher = new RC2Engine();
-                    break;
-                case CipherAlgorithm.RC5:
-                    blockCipher = new RC532Engine();
-                    break;
-                case CipherAlgorithm.RC5_64:
-                    blockCipher = new RC564Engine();
-                    break;
-                case CipherAlgorithm.RC6:
-                    blockCipher = new RC6Engine();
-                    break;
-                case CipherAlgorithm.RIJNDAEL:
-                    blockCipher = new RijndaelEngine();
-                    break;
-                case CipherAlgorithm.RSA:
-                    asymBlockCipher = new RsaBlindedEngine();
-                    break;
-                case CipherAlgorithm.SALSA20:
-                    streamCipher = new Salsa20Engine();
-                    break;
-                case CipherAlgorithm.SEED:
-                    blockCipher = new SeedEngine();
-                    break;
-                case CipherAlgorithm.SERPENT:
-                    blockCipher = new SerpentEngine();
-                    break;
-                case CipherAlgorithm.SKIPJACK:
-                    blockCipher = new SkipjackEngine();
-                    break;
-                case CipherAlgorithm.SM4:
-                    blockCipher = new SM4Engine();
-                    break;
-                case CipherAlgorithm.TEA:
-                    blockCipher = new TeaEngine();
-                    break;
-                case CipherAlgorithm.THREEFISH_256:
-                    blockCipher = new ThreefishEngine(ThreefishEngine.BLOCKSIZE_256);
-                    break;
-                case CipherAlgorithm.THREEFISH_512:
-                    blockCipher = new ThreefishEngine(ThreefishEngine.BLOCKSIZE_512);
-                    break;
-                case CipherAlgorithm.THREEFISH_1024:
-                    blockCipher = new ThreefishEngine(ThreefishEngine.BLOCKSIZE_1024);
-                    break;
-                case CipherAlgorithm.TNEPRES:
-                    blockCipher = new TnepresEngine();
-                    break;
-                case CipherAlgorithm.TWOFISH:
-                    blockCipher = new TwofishEngine();
-                    break;
-                case CipherAlgorithm.VMPC:
-                    streamCipher = new VmpcEngine();
-                    break;
-                case CipherAlgorithm.VMPC_KSA3:
-                    streamCipher = new VmpcKsa3Engine();
-                    break;
-                case CipherAlgorithm.XTEA:
-                    blockCipher = new XteaEngine();
-                    break;
-                default:
-                    throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
+            case CipherAlgorithm.AES:
+                blockCipher = new AesEngine();
+                break;
+            case CipherAlgorithm.ARC4:
+                streamCipher = new RC4Engine();
+                break;
+            case CipherAlgorithm.ARIA:
+                blockCipher = new AriaEngine();
+                break;
+            case CipherAlgorithm.BLOWFISH:
+                blockCipher = new BlowfishEngine();
+                break;
+            case CipherAlgorithm.CAMELLIA:
+                blockCipher = new CamelliaEngine();
+                break;
+            case CipherAlgorithm.CAST5:
+                blockCipher = new Cast5Engine();
+                break;
+            case CipherAlgorithm.CAST6:
+                blockCipher = new Cast6Engine();
+                break;
+            case CipherAlgorithm.CHACHA:
+                streamCipher = new ChaChaEngine();
+                break;
+            case CipherAlgorithm.CHACHA20_POLY1305:
+                aeadCipher = new ChaCha20Poly1305();
+                break;
+            case CipherAlgorithm.CHACHA7539:
+                streamCipher = new ChaCha7539Engine();
+                break;
+            case CipherAlgorithm.DES:
+                blockCipher = new DesEngine();
+                break;
+            case CipherAlgorithm.DESEDE:
+                blockCipher = new DesEdeEngine();
+                break;
+            case CipherAlgorithm.ELGAMAL:
+                asymBlockCipher = new ElGamalEngine();
+                break;
+            case CipherAlgorithm.GOST28147:
+                blockCipher = new Gost28147Engine();
+                break;
+            case CipherAlgorithm.HC128:
+                streamCipher = new HC128Engine();
+                break;
+            case CipherAlgorithm.HC256:
+                streamCipher = new HC256Engine();
+                break;
+            case CipherAlgorithm.IDEA:
+                blockCipher = new IdeaEngine();
+                break;
+            case CipherAlgorithm.NOEKEON:
+                blockCipher = new NoekeonEngine();
+                break;
+            case CipherAlgorithm.PBEWITHSHAAND128BITRC4:
+            case CipherAlgorithm.PBEWITHSHAAND40BITRC4:
+                streamCipher = new RC4Engine();
+                break;
+            case CipherAlgorithm.RC2:
+                blockCipher = new RC2Engine();
+                break;
+            case CipherAlgorithm.RC5:
+                blockCipher = new RC532Engine();
+                break;
+            case CipherAlgorithm.RC5_64:
+                blockCipher = new RC564Engine();
+                break;
+            case CipherAlgorithm.RC6:
+                blockCipher = new RC6Engine();
+                break;
+            case CipherAlgorithm.RIJNDAEL:
+                blockCipher = new RijndaelEngine();
+                break;
+            case CipherAlgorithm.RSA:
+                asymBlockCipher = new RsaBlindedEngine();
+                break;
+            case CipherAlgorithm.SALSA20:
+                streamCipher = new Salsa20Engine();
+                break;
+            case CipherAlgorithm.SEED:
+                blockCipher = new SeedEngine();
+                break;
+            case CipherAlgorithm.SERPENT:
+                blockCipher = new SerpentEngine();
+                break;
+            case CipherAlgorithm.SKIPJACK:
+                blockCipher = new SkipjackEngine();
+                break;
+            case CipherAlgorithm.SM4:
+                blockCipher = new SM4Engine();
+                break;
+            case CipherAlgorithm.TEA:
+                blockCipher = new TeaEngine();
+                break;
+            case CipherAlgorithm.THREEFISH_256:
+                blockCipher = new ThreefishEngine(ThreefishEngine.BLOCKSIZE_256);
+                break;
+            case CipherAlgorithm.THREEFISH_512:
+                blockCipher = new ThreefishEngine(ThreefishEngine.BLOCKSIZE_512);
+                break;
+            case CipherAlgorithm.THREEFISH_1024:
+                blockCipher = new ThreefishEngine(ThreefishEngine.BLOCKSIZE_1024);
+                break;
+            case CipherAlgorithm.TNEPRES:
+                blockCipher = new TnepresEngine();
+                break;
+            case CipherAlgorithm.TWOFISH:
+                blockCipher = new TwofishEngine();
+                break;
+            case CipherAlgorithm.VMPC:
+                streamCipher = new VmpcEngine();
+                break;
+            case CipherAlgorithm.VMPC_KSA3:
+                streamCipher = new VmpcKsa3Engine();
+                break;
+            case CipherAlgorithm.XTEA:
+                blockCipher = new XteaEngine();
+                break;
+            default:
+                throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
             }
 
             if (aeadCipher != null)
@@ -585,81 +541,81 @@ namespace Org.BouncyCastle.Security
 
                 switch (cipherPadding)
                 {
-                    case CipherPadding.NOPADDING:
-                        padded = false;
-                        break;
-                    case CipherPadding.RAW:
-                        break;
-                    case CipherPadding.ISO10126PADDING:
-                    case CipherPadding.ISO10126D2PADDING:
-                    case CipherPadding.ISO10126_2PADDING:
-                        padding = new ISO10126d2Padding();
-                        break;
-                    case CipherPadding.ISO7816_4PADDING:
-                    case CipherPadding.ISO9797_1PADDING:
-                        padding = new ISO7816d4Padding();
-                        break;
-                    case CipherPadding.ISO9796_1:
-                    case CipherPadding.ISO9796_1PADDING:
-                        asymBlockCipher = new ISO9796d1Encoding(asymBlockCipher);
-                        break;
-                    case CipherPadding.OAEP:
-                    case CipherPadding.OAEPPADDING:
-                        asymBlockCipher = new OaepEncoding(asymBlockCipher);
-                        break;
-                    case CipherPadding.OAEPWITHMD5ANDMGF1PADDING:
-                        asymBlockCipher = new OaepEncoding(asymBlockCipher, new MD5Digest());
-                        break;
-                    case CipherPadding.OAEPWITHSHA1ANDMGF1PADDING:
-                    case CipherPadding.OAEPWITHSHA_1ANDMGF1PADDING:
-                        asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha1Digest());
-                        break;
-                    case CipherPadding.OAEPWITHSHA224ANDMGF1PADDING:
-                    case CipherPadding.OAEPWITHSHA_224ANDMGF1PADDING:
-                        asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha224Digest());
-                        break;
-                    case CipherPadding.OAEPWITHSHA256ANDMGF1PADDING:
-                    case CipherPadding.OAEPWITHSHA_256ANDMGF1PADDING:
-                    case CipherPadding.OAEPWITHSHA256ANDMGF1WITHSHA256PADDING:
-                    case CipherPadding.OAEPWITHSHA_256ANDMGF1WITHSHA_256PADDING:
-                        asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha256Digest());
-                        break;
-                    case CipherPadding.OAEPWITHSHA256ANDMGF1WITHSHA1PADDING:
-                    case CipherPadding.OAEPWITHSHA_256ANDMGF1WITHSHA_1PADDING:
-                        asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha256Digest(), new Sha1Digest(), null);
-                        break;
-                    case CipherPadding.OAEPWITHSHA384ANDMGF1PADDING:
-                    case CipherPadding.OAEPWITHSHA_384ANDMGF1PADDING:
-                        asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha384Digest());
-                        break;
-                    case CipherPadding.OAEPWITHSHA512ANDMGF1PADDING:
-                    case CipherPadding.OAEPWITHSHA_512ANDMGF1PADDING:
-                        asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha512Digest());
-                        break;
-                    case CipherPadding.PKCS1:
-                    case CipherPadding.PKCS1PADDING:
-                        asymBlockCipher = new Pkcs1Encoding(asymBlockCipher);
-                        break;
-                    case CipherPadding.PKCS5:
-                    case CipherPadding.PKCS5PADDING:
-                    case CipherPadding.PKCS7:
-                    case CipherPadding.PKCS7PADDING:
-                        padding = new Pkcs7Padding();
-                        break;
-                    case CipherPadding.TBCPADDING:
-                        padding = new TbcPadding();
-                        break;
-                    case CipherPadding.WITHCTS:
-                        cts = true;
-                        break;
-                    case CipherPadding.X923PADDING:
-                        padding = new X923Padding();
-                        break;
-                    case CipherPadding.ZEROBYTEPADDING:
-                        padding = new ZeroBytePadding();
-                        break;
-                    default:
-                        throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
+                case CipherPadding.NOPADDING:
+                    padded = false;
+                    break;
+                case CipherPadding.RAW:
+                    break;
+                case CipherPadding.ISO10126PADDING:
+                case CipherPadding.ISO10126D2PADDING:
+                case CipherPadding.ISO10126_2PADDING:
+                    padding = new ISO10126d2Padding();
+                    break;
+                case CipherPadding.ISO7816_4PADDING:
+                case CipherPadding.ISO9797_1PADDING:
+                    padding = new ISO7816d4Padding();
+                    break;
+                case CipherPadding.ISO9796_1:
+                case CipherPadding.ISO9796_1PADDING:
+                    asymBlockCipher = new ISO9796d1Encoding(asymBlockCipher);
+                    break;
+                case CipherPadding.OAEP:
+                case CipherPadding.OAEPPADDING:
+                    asymBlockCipher = new OaepEncoding(asymBlockCipher);
+                    break;
+                case CipherPadding.OAEPWITHMD5ANDMGF1PADDING:
+                    asymBlockCipher = new OaepEncoding(asymBlockCipher, new MD5Digest());
+                    break;
+                case CipherPadding.OAEPWITHSHA1ANDMGF1PADDING:
+                case CipherPadding.OAEPWITHSHA_1ANDMGF1PADDING:
+                    asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha1Digest());
+                    break;
+                case CipherPadding.OAEPWITHSHA224ANDMGF1PADDING:
+                case CipherPadding.OAEPWITHSHA_224ANDMGF1PADDING:
+                    asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha224Digest());
+                    break;
+                case CipherPadding.OAEPWITHSHA256ANDMGF1PADDING:
+                case CipherPadding.OAEPWITHSHA_256ANDMGF1PADDING:
+                case CipherPadding.OAEPWITHSHA256ANDMGF1WITHSHA256PADDING:
+                case CipherPadding.OAEPWITHSHA_256ANDMGF1WITHSHA_256PADDING:
+                    asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha256Digest());
+                    break;
+                case CipherPadding.OAEPWITHSHA256ANDMGF1WITHSHA1PADDING:
+                case CipherPadding.OAEPWITHSHA_256ANDMGF1WITHSHA_1PADDING:
+                    asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha256Digest(), new Sha1Digest(), null);
+                    break;
+                case CipherPadding.OAEPWITHSHA384ANDMGF1PADDING:
+                case CipherPadding.OAEPWITHSHA_384ANDMGF1PADDING:
+                    asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha384Digest());
+                    break;
+                case CipherPadding.OAEPWITHSHA512ANDMGF1PADDING:
+                case CipherPadding.OAEPWITHSHA_512ANDMGF1PADDING:
+                    asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha512Digest());
+                    break;
+                case CipherPadding.PKCS1:
+                case CipherPadding.PKCS1PADDING:
+                    asymBlockCipher = new Pkcs1Encoding(asymBlockCipher);
+                    break;
+                case CipherPadding.PKCS5:
+                case CipherPadding.PKCS5PADDING:
+                case CipherPadding.PKCS7:
+                case CipherPadding.PKCS7PADDING:
+                    padding = new Pkcs7Padding();
+                    break;
+                case CipherPadding.TBCPADDING:
+                    padding = new TbcPadding();
+                    break;
+                case CipherPadding.WITHCTS:
+                    cts = true;
+                    break;
+                case CipherPadding.X923PADDING:
+                    padding = new X923Padding();
+                    break;
+                case CipherPadding.ZEROBYTEPADDING:
+                    padding = new ZeroBytePadding();
+                    break;
+                default:
+                    throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
                 }
             }
 
@@ -679,64 +635,64 @@ namespace Org.BouncyCastle.Security
 
                     switch (cipherMode)
                     {
-                        case CipherMode.ECB:
-                        case CipherMode.NONE:
-                            break;
-                        case CipherMode.CBC:
-                            blockCipher = new CbcBlockCipher(blockCipher);
-                            break;
-                        case CipherMode.CCM:
-                            aeadBlockCipher = new CcmBlockCipher(blockCipher);
-                            break;
-                        case CipherMode.CFB:
-                        {
-                            int bits = (di < 0)
-                                ?	8 * blockCipher.GetBlockSize()
-                                :	int.Parse(mode.Substring(di));
+                    case CipherMode.ECB:
+                    case CipherMode.NONE:
+                        break;
+                    case CipherMode.CBC:
+                        blockCipher = new CbcBlockCipher(blockCipher);
+                        break;
+                    case CipherMode.CCM:
+                        aeadBlockCipher = new CcmBlockCipher(blockCipher);
+                        break;
+                    case CipherMode.CFB:
+                    {
+                        int bits = (di < 0)
+                            ?	8 * blockCipher.GetBlockSize()
+                            :	int.Parse(mode.Substring(di));
     
-                            blockCipher = new CfbBlockCipher(blockCipher, bits);
-                            break;
-                        }
-                        case CipherMode.CTR:
-                            blockCipher = new SicBlockCipher(blockCipher);
-                            break;
-                        case CipherMode.CTS:
-                            cts = true;
-                            blockCipher = new CbcBlockCipher(blockCipher);
-                            break;
-                        case CipherMode.EAX:
-                            aeadBlockCipher = new EaxBlockCipher(blockCipher);
-                            break;
-                        case CipherMode.GCM:
-                            aeadBlockCipher = new GcmBlockCipher(blockCipher);
-                            break;
-                        case CipherMode.GOFB:
-                            blockCipher = new GOfbBlockCipher(blockCipher);
-                            break;
-                        case CipherMode.OCB:
-                            aeadBlockCipher = new OcbBlockCipher(blockCipher, CreateBlockCipher(cipherAlgorithm));
-                            break;
-                        case CipherMode.OFB:
-                        {
-                            int bits = (di < 0)
-                                ?	8 * blockCipher.GetBlockSize()
-                                :	int.Parse(mode.Substring(di));
+                        blockCipher = new CfbBlockCipher(blockCipher, bits);
+                        break;
+                    }
+                    case CipherMode.CTR:
+                        blockCipher = new SicBlockCipher(blockCipher);
+                        break;
+                    case CipherMode.CTS:
+                        cts = true;
+                        blockCipher = new CbcBlockCipher(blockCipher);
+                        break;
+                    case CipherMode.EAX:
+                        aeadBlockCipher = new EaxBlockCipher(blockCipher);
+                        break;
+                    case CipherMode.GCM:
+                        aeadBlockCipher = new GcmBlockCipher(blockCipher);
+                        break;
+                    case CipherMode.GOFB:
+                        blockCipher = new GOfbBlockCipher(blockCipher);
+                        break;
+                    case CipherMode.OCB:
+                        aeadBlockCipher = new OcbBlockCipher(blockCipher, CreateBlockCipher(cipherAlgorithm));
+                        break;
+                    case CipherMode.OFB:
+                    {
+                        int bits = (di < 0)
+                            ?	8 * blockCipher.GetBlockSize()
+                            :	int.Parse(mode.Substring(di));
     
-                            blockCipher = new OfbBlockCipher(blockCipher, bits);
-                            break;
+                        blockCipher = new OfbBlockCipher(blockCipher, bits);
+                        break;
+                    }
+                    case CipherMode.OPENPGPCFB:
+                        blockCipher = new OpenPgpCfbBlockCipher(blockCipher);
+                        break;
+                    case CipherMode.SIC:
+                        if (blockCipher.GetBlockSize() < 16)
+                        {
+                            throw new ArgumentException("Warning: SIC-Mode can become a twotime-pad if the blocksize of the cipher is too small. Use a cipher with a block size of at least 128 bits (e.g. AES)");
                         }
-                        case CipherMode.OPENPGPCFB:
-                            blockCipher = new OpenPgpCfbBlockCipher(blockCipher);
-                            break;
-                        case CipherMode.SIC:
-                            if (blockCipher.GetBlockSize() < 16)
-                            {
-                                throw new ArgumentException("Warning: SIC-Mode can become a twotime-pad if the blocksize of the cipher is too small. Use a cipher with a block size of at least 128 bits (e.g. AES)");
-                            }
-                            blockCipher = new SicBlockCipher(blockCipher);
-                            break;
-                        default:
-                            throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
+                        blockCipher = new SicBlockCipher(blockCipher);
+                        break;
+                    default:
+                        throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
                     }
                 }
                 catch (ArgumentException)
@@ -783,14 +739,12 @@ namespace Org.BouncyCastle.Security
             throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
         }
 
-        public static string GetAlgorithmName(
-            DerObjectIdentifier oid)
+        public static string GetAlgorithmName(DerObjectIdentifier oid)
         {
-            return (string) algorithms[oid.Id];
+            return CollectionUtilities.GetValueOrNull(Algorithms, oid.Id);
         }
 
-        private static int GetDigitIndex(
-            string s)
+        private static int GetDigitIndex(string s)
         {
             for (int i = 0; i < s.Length; ++i)
             {
@@ -805,35 +759,35 @@ namespace Org.BouncyCastle.Security
         {
             switch (cipherAlgorithm)
             {
-                case CipherAlgorithm.AES: return new AesEngine();
-                case CipherAlgorithm.ARIA: return new AriaEngine();
-                case CipherAlgorithm.BLOWFISH: return new BlowfishEngine();
-                case CipherAlgorithm.CAMELLIA: return new CamelliaEngine();
-                case CipherAlgorithm.CAST5: return new Cast5Engine();
-                case CipherAlgorithm.CAST6: return new Cast6Engine();
-                case CipherAlgorithm.DES: return new DesEngine();
-                case CipherAlgorithm.DESEDE: return new DesEdeEngine();
-                case CipherAlgorithm.GOST28147: return new Gost28147Engine();
-                case CipherAlgorithm.IDEA: return new IdeaEngine();
-                case CipherAlgorithm.NOEKEON: return new NoekeonEngine();
-                case CipherAlgorithm.RC2: return new RC2Engine();
-                case CipherAlgorithm.RC5: return new RC532Engine();
-                case CipherAlgorithm.RC5_64: return new RC564Engine();
-                case CipherAlgorithm.RC6: return new RC6Engine();
-                case CipherAlgorithm.RIJNDAEL: return new RijndaelEngine();
-                case CipherAlgorithm.SEED: return new SeedEngine();
-                case CipherAlgorithm.SERPENT: return new SerpentEngine();
-                case CipherAlgorithm.SKIPJACK: return new SkipjackEngine();
-                case CipherAlgorithm.SM4: return new SM4Engine();
-                case CipherAlgorithm.TEA: return new TeaEngine();
-                case CipherAlgorithm.THREEFISH_256: return new ThreefishEngine(ThreefishEngine.BLOCKSIZE_256);
-                case CipherAlgorithm.THREEFISH_512: return new ThreefishEngine(ThreefishEngine.BLOCKSIZE_512);
-                case CipherAlgorithm.THREEFISH_1024: return new ThreefishEngine(ThreefishEngine.BLOCKSIZE_1024);
-                case CipherAlgorithm.TNEPRES: return new TnepresEngine();
-                case CipherAlgorithm.TWOFISH: return new TwofishEngine();
-                case CipherAlgorithm.XTEA: return new XteaEngine();
-                default:
-                    throw new SecurityUtilityException("Cipher " + cipherAlgorithm + " not recognised or not a block cipher");
+            case CipherAlgorithm.AES: return new AesEngine();
+            case CipherAlgorithm.ARIA: return new AriaEngine();
+            case CipherAlgorithm.BLOWFISH: return new BlowfishEngine();
+            case CipherAlgorithm.CAMELLIA: return new CamelliaEngine();
+            case CipherAlgorithm.CAST5: return new Cast5Engine();
+            case CipherAlgorithm.CAST6: return new Cast6Engine();
+            case CipherAlgorithm.DES: return new DesEngine();
+            case CipherAlgorithm.DESEDE: return new DesEdeEngine();
+            case CipherAlgorithm.GOST28147: return new Gost28147Engine();
+            case CipherAlgorithm.IDEA: return new IdeaEngine();
+            case CipherAlgorithm.NOEKEON: return new NoekeonEngine();
+            case CipherAlgorithm.RC2: return new RC2Engine();
+            case CipherAlgorithm.RC5: return new RC532Engine();
+            case CipherAlgorithm.RC5_64: return new RC564Engine();
+            case CipherAlgorithm.RC6: return new RC6Engine();
+            case CipherAlgorithm.RIJNDAEL: return new RijndaelEngine();
+            case CipherAlgorithm.SEED: return new SeedEngine();
+            case CipherAlgorithm.SERPENT: return new SerpentEngine();
+            case CipherAlgorithm.SKIPJACK: return new SkipjackEngine();
+            case CipherAlgorithm.SM4: return new SM4Engine();
+            case CipherAlgorithm.TEA: return new TeaEngine();
+            case CipherAlgorithm.THREEFISH_256: return new ThreefishEngine(ThreefishEngine.BLOCKSIZE_256);
+            case CipherAlgorithm.THREEFISH_512: return new ThreefishEngine(ThreefishEngine.BLOCKSIZE_512);
+            case CipherAlgorithm.THREEFISH_1024: return new ThreefishEngine(ThreefishEngine.BLOCKSIZE_1024);
+            case CipherAlgorithm.TNEPRES: return new TnepresEngine();
+            case CipherAlgorithm.TWOFISH: return new TwofishEngine();
+            case CipherAlgorithm.XTEA: return new XteaEngine();
+            default:
+                throw new SecurityUtilityException("Cipher " + cipherAlgorithm + " not recognised or not a block cipher");
             }
         }
     }
diff --git a/crypto/src/security/DigestUtilities.cs b/crypto/src/security/DigestUtilities.cs
index c67dd8b72..2c9e89277 100644
--- a/crypto/src/security/DigestUtilities.cs
+++ b/crypto/src/security/DigestUtilities.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.CryptoPro;
@@ -11,17 +11,17 @@ using Org.BouncyCastle.Asn1.Oiw;
 using Org.BouncyCastle.Asn1.Rosstandart;
 using Org.BouncyCastle.Asn1.TeleTrust;
 using Org.BouncyCastle.Asn1.UA;
-using Org.BouncyCastle.Security;
-using Org.BouncyCastle.Crypto.Digests;
 using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Digests;
 using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Collections;
 
 namespace Org.BouncyCastle.Security
 {
     /// <remarks>
     ///  Utility class for creating IDigest objects from their names/Oids
     /// </remarks>
-    public sealed class DigestUtilities
+    public static class DigestUtilities
     {
         private enum DigestAlgorithm {
             BLAKE2B_160, BLAKE2B_256, BLAKE2B_384, BLAKE2B_512,
@@ -42,130 +42,128 @@ namespace Org.BouncyCastle.Security
             WHIRLPOOL,
         };
 
-        private DigestUtilities()
-        {
-        }
-
-        private static readonly IDictionary algorithms = Platform.CreateHashtable();
-        private static readonly IDictionary oids = Platform.CreateHashtable();
+        private static readonly IDictionary<string, string> Aliases =
+            new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
+        private static readonly IDictionary<string, DerObjectIdentifier> Oids =
+            new Dictionary<string, DerObjectIdentifier>(StringComparer.OrdinalIgnoreCase);
 
         static DigestUtilities()
         {
             // Signal to obfuscation tools not to change enum constants
             ((DigestAlgorithm)Enums.GetArbitraryValue(typeof(DigestAlgorithm))).ToString();
 
-            algorithms[PkcsObjectIdentifiers.MD2.Id] = "MD2";
-            algorithms[PkcsObjectIdentifiers.MD4.Id] = "MD4";
-            algorithms[PkcsObjectIdentifiers.MD5.Id] = "MD5";
-
-            algorithms["SHA1"] = "SHA-1";
-            algorithms[OiwObjectIdentifiers.IdSha1.Id] = "SHA-1";
-            algorithms[PkcsObjectIdentifiers.IdHmacWithSha1.Id] = "SHA-1";
-            algorithms[MiscObjectIdentifiers.HMAC_SHA1.Id] = "SHA-1";
-            algorithms["SHA224"] = "SHA-224";
-            algorithms[NistObjectIdentifiers.IdSha224.Id] = "SHA-224";
-            algorithms[PkcsObjectIdentifiers.IdHmacWithSha224.Id] = "SHA-224";
-            algorithms["SHA256"] = "SHA-256";
-            algorithms[NistObjectIdentifiers.IdSha256.Id] = "SHA-256";
-            algorithms[PkcsObjectIdentifiers.IdHmacWithSha256.Id] = "SHA-256";
-            algorithms["SHA384"] = "SHA-384";
-            algorithms[NistObjectIdentifiers.IdSha384.Id] = "SHA-384";
-            algorithms[PkcsObjectIdentifiers.IdHmacWithSha384.Id] = "SHA-384";
-            algorithms["SHA512"] = "SHA-512";
-            algorithms[NistObjectIdentifiers.IdSha512.Id] = "SHA-512";
-            algorithms[PkcsObjectIdentifiers.IdHmacWithSha512.Id] = "SHA-512";
-
-            algorithms["SHA512/224"] = "SHA-512/224";
-            algorithms["SHA512(224)"] = "SHA-512/224";
-            algorithms["SHA-512(224)"] = "SHA-512/224";
-            algorithms[NistObjectIdentifiers.IdSha512_224.Id] = "SHA-512/224";
-            algorithms["SHA512/256"] = "SHA-512/256";
-            algorithms["SHA512(256)"] = "SHA-512/256";
-            algorithms["SHA-512(256)"] = "SHA-512/256";
-            algorithms[NistObjectIdentifiers.IdSha512_256.Id] = "SHA-512/256";
-
-            algorithms["RIPEMD-128"] = "RIPEMD128";
-            algorithms[TeleTrusTObjectIdentifiers.RipeMD128.Id] = "RIPEMD128";
-            algorithms["RIPEMD-160"] = "RIPEMD160";
-            algorithms[TeleTrusTObjectIdentifiers.RipeMD160.Id] = "RIPEMD160";
-            algorithms["RIPEMD-256"] = "RIPEMD256";
-            algorithms[TeleTrusTObjectIdentifiers.RipeMD256.Id] = "RIPEMD256";
-            algorithms["RIPEMD-320"] = "RIPEMD320";
-//			algorithms[TeleTrusTObjectIdentifiers.RipeMD320.Id] = "RIPEMD320";
-
-            algorithms[CryptoProObjectIdentifiers.GostR3411.Id] = "GOST3411";
-
-            algorithms["KECCAK224"] = "KECCAK-224";
-            algorithms["KECCAK256"] = "KECCAK-256";
-            algorithms["KECCAK288"] = "KECCAK-288";
-            algorithms["KECCAK384"] = "KECCAK-384";
-            algorithms["KECCAK512"] = "KECCAK-512";
-
-            algorithms[NistObjectIdentifiers.IdSha3_224.Id] = "SHA3-224";
-            algorithms[NistObjectIdentifiers.IdHMacWithSha3_224.Id] = "SHA3-224";
-            algorithms[NistObjectIdentifiers.IdSha3_256.Id] = "SHA3-256";
-            algorithms[NistObjectIdentifiers.IdHMacWithSha3_256.Id] = "SHA3-256";
-            algorithms[NistObjectIdentifiers.IdSha3_384.Id] = "SHA3-384";
-            algorithms[NistObjectIdentifiers.IdHMacWithSha3_384.Id] = "SHA3-384";
-            algorithms[NistObjectIdentifiers.IdSha3_512.Id] = "SHA3-512";
-            algorithms[NistObjectIdentifiers.IdHMacWithSha3_512.Id] = "SHA3-512";
-            algorithms["SHAKE128"] = "SHAKE128-256";
-            algorithms[NistObjectIdentifiers.IdShake128.Id] = "SHAKE128-256";
-            algorithms["SHAKE256"] = "SHAKE256-512";
-            algorithms[NistObjectIdentifiers.IdShake256.Id] = "SHAKE256-512";
-
-            algorithms[GMObjectIdentifiers.sm3.Id] = "SM3";
-
-            algorithms[MiscObjectIdentifiers.id_blake2b160.Id] = "BLAKE2B-160";
-            algorithms[MiscObjectIdentifiers.id_blake2b256.Id] = "BLAKE2B-256";
-            algorithms[MiscObjectIdentifiers.id_blake2b384.Id] = "BLAKE2B-384";
-            algorithms[MiscObjectIdentifiers.id_blake2b512.Id] = "BLAKE2B-512";
-            algorithms[MiscObjectIdentifiers.id_blake2s128.Id] = "BLAKE2S-128";
-            algorithms[MiscObjectIdentifiers.id_blake2s160.Id] = "BLAKE2S-160";
-            algorithms[MiscObjectIdentifiers.id_blake2s224.Id] = "BLAKE2S-224";
-            algorithms[MiscObjectIdentifiers.id_blake2s256.Id] = "BLAKE2S-256";
-
-            algorithms[RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256.Id] = "GOST3411-2012-256";
-            algorithms[RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512.Id] = "GOST3411-2012-512";
-
-            algorithms[UAObjectIdentifiers.dstu7564digest_256.Id] = "DSTU7564-256";
-            algorithms[UAObjectIdentifiers.dstu7564digest_384.Id] = "DSTU7564-384";
-            algorithms[UAObjectIdentifiers.dstu7564digest_512.Id] = "DSTU7564-512";
-
-            oids["MD2"] = PkcsObjectIdentifiers.MD2;
-            oids["MD4"] = PkcsObjectIdentifiers.MD4;
-            oids["MD5"] = PkcsObjectIdentifiers.MD5;
-            oids["SHA-1"] = OiwObjectIdentifiers.IdSha1;
-            oids["SHA-224"] = NistObjectIdentifiers.IdSha224;
-            oids["SHA-256"] = NistObjectIdentifiers.IdSha256;
-            oids["SHA-384"] = NistObjectIdentifiers.IdSha384;
-            oids["SHA-512"] = NistObjectIdentifiers.IdSha512;
-            oids["SHA-512/224"] = NistObjectIdentifiers.IdSha512_224;
-            oids["SHA-512/256"] = NistObjectIdentifiers.IdSha512_256;
-            oids["SHA3-224"] = NistObjectIdentifiers.IdSha3_224;
-            oids["SHA3-256"] = NistObjectIdentifiers.IdSha3_256;
-            oids["SHA3-384"] = NistObjectIdentifiers.IdSha3_384;
-            oids["SHA3-512"] = NistObjectIdentifiers.IdSha3_512;
-            oids["SHAKE128-256"] = NistObjectIdentifiers.IdShake128;
-            oids["SHAKE256-512"] = NistObjectIdentifiers.IdShake256;
-            oids["RIPEMD128"] = TeleTrusTObjectIdentifiers.RipeMD128;
-            oids["RIPEMD160"] = TeleTrusTObjectIdentifiers.RipeMD160;
-            oids["RIPEMD256"] = TeleTrusTObjectIdentifiers.RipeMD256;
-            oids["GOST3411"] = CryptoProObjectIdentifiers.GostR3411;
-            oids["SM3"] = GMObjectIdentifiers.sm3;
-            oids["BLAKE2B-160"] = MiscObjectIdentifiers.id_blake2b160;
-            oids["BLAKE2B-256"] = MiscObjectIdentifiers.id_blake2b256;
-            oids["BLAKE2B-384"] = MiscObjectIdentifiers.id_blake2b384;
-            oids["BLAKE2B-512"] = MiscObjectIdentifiers.id_blake2b512;
-            oids["BLAKE2S-128"] = MiscObjectIdentifiers.id_blake2s128;
-            oids["BLAKE2S-160"] = MiscObjectIdentifiers.id_blake2s160;
-            oids["BLAKE2S-224"] = MiscObjectIdentifiers.id_blake2s224;
-            oids["BLAKE2S-256"] = MiscObjectIdentifiers.id_blake2s256;
-            oids["GOST3411-2012-256"] = RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256;
-            oids["GOST3411-2012-512"] = RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512;
-            oids["DSTU7564-256"] = UAObjectIdentifiers.dstu7564digest_256;
-            oids["DSTU7564-384"] = UAObjectIdentifiers.dstu7564digest_384;
-            oids["DSTU7564-512"] = UAObjectIdentifiers.dstu7564digest_512;
+            Aliases[PkcsObjectIdentifiers.MD2.Id] = "MD2";
+            Aliases[PkcsObjectIdentifiers.MD4.Id] = "MD4";
+            Aliases[PkcsObjectIdentifiers.MD5.Id] = "MD5";
+
+            Aliases["SHA1"] = "SHA-1";
+            Aliases[OiwObjectIdentifiers.IdSha1.Id] = "SHA-1";
+            Aliases[PkcsObjectIdentifiers.IdHmacWithSha1.Id] = "SHA-1";
+            Aliases[MiscObjectIdentifiers.HMAC_SHA1.Id] = "SHA-1";
+            Aliases["SHA224"] = "SHA-224";
+            Aliases[NistObjectIdentifiers.IdSha224.Id] = "SHA-224";
+            Aliases[PkcsObjectIdentifiers.IdHmacWithSha224.Id] = "SHA-224";
+            Aliases["SHA256"] = "SHA-256";
+            Aliases[NistObjectIdentifiers.IdSha256.Id] = "SHA-256";
+            Aliases[PkcsObjectIdentifiers.IdHmacWithSha256.Id] = "SHA-256";
+            Aliases["SHA384"] = "SHA-384";
+            Aliases[NistObjectIdentifiers.IdSha384.Id] = "SHA-384";
+            Aliases[PkcsObjectIdentifiers.IdHmacWithSha384.Id] = "SHA-384";
+            Aliases["SHA512"] = "SHA-512";
+            Aliases[NistObjectIdentifiers.IdSha512.Id] = "SHA-512";
+            Aliases[PkcsObjectIdentifiers.IdHmacWithSha512.Id] = "SHA-512";
+
+            Aliases["SHA512/224"] = "SHA-512/224";
+            Aliases["SHA512(224)"] = "SHA-512/224";
+            Aliases["SHA-512(224)"] = "SHA-512/224";
+            Aliases[NistObjectIdentifiers.IdSha512_224.Id] = "SHA-512/224";
+            Aliases["SHA512/256"] = "SHA-512/256";
+            Aliases["SHA512(256)"] = "SHA-512/256";
+            Aliases["SHA-512(256)"] = "SHA-512/256";
+            Aliases[NistObjectIdentifiers.IdSha512_256.Id] = "SHA-512/256";
+
+            Aliases["RIPEMD-128"] = "RIPEMD128";
+            Aliases[TeleTrusTObjectIdentifiers.RipeMD128.Id] = "RIPEMD128";
+            Aliases["RIPEMD-160"] = "RIPEMD160";
+            Aliases[TeleTrusTObjectIdentifiers.RipeMD160.Id] = "RIPEMD160";
+            Aliases["RIPEMD-256"] = "RIPEMD256";
+            Aliases[TeleTrusTObjectIdentifiers.RipeMD256.Id] = "RIPEMD256";
+            Aliases["RIPEMD-320"] = "RIPEMD320";
+            //Aliases[TeleTrusTObjectIdentifiers.RipeMD320.Id] = "RIPEMD320";
+
+            Aliases[CryptoProObjectIdentifiers.GostR3411.Id] = "GOST3411";
+
+            Aliases["KECCAK224"] = "KECCAK-224";
+            Aliases["KECCAK256"] = "KECCAK-256";
+            Aliases["KECCAK288"] = "KECCAK-288";
+            Aliases["KECCAK384"] = "KECCAK-384";
+            Aliases["KECCAK512"] = "KECCAK-512";
+
+            Aliases[NistObjectIdentifiers.IdSha3_224.Id] = "SHA3-224";
+            Aliases[NistObjectIdentifiers.IdHMacWithSha3_224.Id] = "SHA3-224";
+            Aliases[NistObjectIdentifiers.IdSha3_256.Id] = "SHA3-256";
+            Aliases[NistObjectIdentifiers.IdHMacWithSha3_256.Id] = "SHA3-256";
+            Aliases[NistObjectIdentifiers.IdSha3_384.Id] = "SHA3-384";
+            Aliases[NistObjectIdentifiers.IdHMacWithSha3_384.Id] = "SHA3-384";
+            Aliases[NistObjectIdentifiers.IdSha3_512.Id] = "SHA3-512";
+            Aliases[NistObjectIdentifiers.IdHMacWithSha3_512.Id] = "SHA3-512";
+            Aliases["SHAKE128"] = "SHAKE128-256";
+            Aliases[NistObjectIdentifiers.IdShake128.Id] = "SHAKE128-256";
+            Aliases["SHAKE256"] = "SHAKE256-512";
+            Aliases[NistObjectIdentifiers.IdShake256.Id] = "SHAKE256-512";
+
+            Aliases[GMObjectIdentifiers.sm3.Id] = "SM3";
+
+            Aliases[MiscObjectIdentifiers.id_blake2b160.Id] = "BLAKE2B-160";
+            Aliases[MiscObjectIdentifiers.id_blake2b256.Id] = "BLAKE2B-256";
+            Aliases[MiscObjectIdentifiers.id_blake2b384.Id] = "BLAKE2B-384";
+            Aliases[MiscObjectIdentifiers.id_blake2b512.Id] = "BLAKE2B-512";
+            Aliases[MiscObjectIdentifiers.id_blake2s128.Id] = "BLAKE2S-128";
+            Aliases[MiscObjectIdentifiers.id_blake2s160.Id] = "BLAKE2S-160";
+            Aliases[MiscObjectIdentifiers.id_blake2s224.Id] = "BLAKE2S-224";
+            Aliases[MiscObjectIdentifiers.id_blake2s256.Id] = "BLAKE2S-256";
+
+            Aliases[RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256.Id] = "GOST3411-2012-256";
+            Aliases[RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512.Id] = "GOST3411-2012-512";
+
+            Aliases[UAObjectIdentifiers.dstu7564digest_256.Id] = "DSTU7564-256";
+            Aliases[UAObjectIdentifiers.dstu7564digest_384.Id] = "DSTU7564-384";
+            Aliases[UAObjectIdentifiers.dstu7564digest_512.Id] = "DSTU7564-512";
+
+            Oids["MD2"] = PkcsObjectIdentifiers.MD2;
+            Oids["MD4"] = PkcsObjectIdentifiers.MD4;
+            Oids["MD5"] = PkcsObjectIdentifiers.MD5;
+            Oids["SHA-1"] = OiwObjectIdentifiers.IdSha1;
+            Oids["SHA-224"] = NistObjectIdentifiers.IdSha224;
+            Oids["SHA-256"] = NistObjectIdentifiers.IdSha256;
+            Oids["SHA-384"] = NistObjectIdentifiers.IdSha384;
+            Oids["SHA-512"] = NistObjectIdentifiers.IdSha512;
+            Oids["SHA-512/224"] = NistObjectIdentifiers.IdSha512_224;
+            Oids["SHA-512/256"] = NistObjectIdentifiers.IdSha512_256;
+            Oids["SHA3-224"] = NistObjectIdentifiers.IdSha3_224;
+            Oids["SHA3-256"] = NistObjectIdentifiers.IdSha3_256;
+            Oids["SHA3-384"] = NistObjectIdentifiers.IdSha3_384;
+            Oids["SHA3-512"] = NistObjectIdentifiers.IdSha3_512;
+            Oids["SHAKE128-256"] = NistObjectIdentifiers.IdShake128;
+            Oids["SHAKE256-512"] = NistObjectIdentifiers.IdShake256;
+            Oids["RIPEMD128"] = TeleTrusTObjectIdentifiers.RipeMD128;
+            Oids["RIPEMD160"] = TeleTrusTObjectIdentifiers.RipeMD160;
+            Oids["RIPEMD256"] = TeleTrusTObjectIdentifiers.RipeMD256;
+            Oids["GOST3411"] = CryptoProObjectIdentifiers.GostR3411;
+            Oids["SM3"] = GMObjectIdentifiers.sm3;
+            Oids["BLAKE2B-160"] = MiscObjectIdentifiers.id_blake2b160;
+            Oids["BLAKE2B-256"] = MiscObjectIdentifiers.id_blake2b256;
+            Oids["BLAKE2B-384"] = MiscObjectIdentifiers.id_blake2b384;
+            Oids["BLAKE2B-512"] = MiscObjectIdentifiers.id_blake2b512;
+            Oids["BLAKE2S-128"] = MiscObjectIdentifiers.id_blake2s128;
+            Oids["BLAKE2S-160"] = MiscObjectIdentifiers.id_blake2s160;
+            Oids["BLAKE2S-224"] = MiscObjectIdentifiers.id_blake2s224;
+            Oids["BLAKE2S-256"] = MiscObjectIdentifiers.id_blake2s256;
+            Oids["GOST3411-2012-256"] = RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256;
+            Oids["GOST3411-2012-512"] = RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512;
+            Oids["DSTU7564-256"] = UAObjectIdentifiers.dstu7564digest_256;
+            Oids["DSTU7564-384"] = UAObjectIdentifiers.dstu7564digest_384;
+            Oids["DSTU7564-512"] = UAObjectIdentifiers.dstu7564digest_512;
         }
 
         /// <summary>
@@ -174,42 +172,27 @@ namespace Org.BouncyCastle.Security
         /// <param name="mechanism">A string representation of the digest meanism.</param>
         /// <returns>A DerObjectIdentifier, null if the Oid is not available.</returns>
 
-        public static DerObjectIdentifier GetObjectIdentifier(
-            string mechanism)
+        public static DerObjectIdentifier GetObjectIdentifier(string mechanism)
         {
             if (mechanism == null)
-                throw new System.ArgumentNullException("mechanism");
-
-            mechanism = Platform.ToUpperInvariant(mechanism);
-            string aliased = (string) algorithms[mechanism];
+                throw new ArgumentNullException(nameof(mechanism));
 
-            if (aliased != null)
-                mechanism = aliased;
+            mechanism = CollectionUtilities.GetValueOrKey(Aliases, mechanism).ToUpperInvariant();
 
-            return (DerObjectIdentifier) oids[mechanism];
+            return CollectionUtilities.GetValueOrNull(Oids, mechanism);
         }
 
-        public static ICollection Algorithms
-        {
-            get { return oids.Keys; }
-        }
-
-        public static IDigest GetDigest(
-            DerObjectIdentifier id)
+        public static IDigest GetDigest(DerObjectIdentifier id)
         {
             return GetDigest(id.Id);
         }
 
-        public static IDigest GetDigest(
-            string algorithm)
+        public static IDigest GetDigest(string algorithm)
         {
-            string upper = Platform.ToUpperInvariant(algorithm);
-            string mechanism = (string) algorithms[upper];
+            if (algorithm == null)
+                throw new ArgumentNullException(nameof(algorithm));
 
-            if (mechanism == null)
-            {
-                mechanism = upper;
-            }
+            string mechanism = CollectionUtilities.GetValueOrKey(Aliases, algorithm).ToUpperInvariant();
 
             try
             {
@@ -218,49 +201,49 @@ namespace Org.BouncyCastle.Security
 
                 switch (digestAlgorithm)
                 {
-                    case DigestAlgorithm.BLAKE2B_160: return new Blake2bDigest(160);
-                    case DigestAlgorithm.BLAKE2B_256: return new Blake2bDigest(256);
-                    case DigestAlgorithm.BLAKE2B_384: return new Blake2bDigest(384);
-                    case DigestAlgorithm.BLAKE2B_512: return new Blake2bDigest(512);
-                    case DigestAlgorithm.BLAKE2S_128: return new Blake2sDigest(128);
-                    case DigestAlgorithm.BLAKE2S_160: return new Blake2sDigest(160);
-                    case DigestAlgorithm.BLAKE2S_224: return new Blake2sDigest(224);
-                    case DigestAlgorithm.BLAKE2S_256: return new Blake2sDigest(256);
-                    case DigestAlgorithm.DSTU7564_256: return new Dstu7564Digest(256);
-                    case DigestAlgorithm.DSTU7564_384: return new Dstu7564Digest(384);
-                    case DigestAlgorithm.DSTU7564_512: return new Dstu7564Digest(512);
-                    case DigestAlgorithm.GOST3411: return new Gost3411Digest();
-                    case DigestAlgorithm.GOST3411_2012_256: return new Gost3411_2012_256Digest();
-                    case DigestAlgorithm.GOST3411_2012_512: return new Gost3411_2012_512Digest();
-                    case DigestAlgorithm.KECCAK_224: return new KeccakDigest(224);
-                    case DigestAlgorithm.KECCAK_256: return new KeccakDigest(256);
-                    case DigestAlgorithm.KECCAK_288: return new KeccakDigest(288);
-                    case DigestAlgorithm.KECCAK_384: return new KeccakDigest(384);
-                    case DigestAlgorithm.KECCAK_512: return new KeccakDigest(512);
-                    case DigestAlgorithm.MD2: return new MD2Digest();
-                    case DigestAlgorithm.MD4: return new MD4Digest();
-                    case DigestAlgorithm.MD5: return new MD5Digest();
-                    case DigestAlgorithm.NONE: return new NullDigest();
-                    case DigestAlgorithm.RIPEMD128: return new RipeMD128Digest();
-                    case DigestAlgorithm.RIPEMD160: return new RipeMD160Digest();
-                    case DigestAlgorithm.RIPEMD256: return new RipeMD256Digest();
-                    case DigestAlgorithm.RIPEMD320: return new RipeMD320Digest();
-                    case DigestAlgorithm.SHA_1: return new Sha1Digest();
-                    case DigestAlgorithm.SHA_224: return new Sha224Digest();
-                    case DigestAlgorithm.SHA_256: return new Sha256Digest();
-                    case DigestAlgorithm.SHA_384: return new Sha384Digest();
-                    case DigestAlgorithm.SHA_512: return new Sha512Digest();
-                    case DigestAlgorithm.SHA_512_224: return new Sha512tDigest(224);
-                    case DigestAlgorithm.SHA_512_256: return new Sha512tDigest(256);
-                    case DigestAlgorithm.SHA3_224: return new Sha3Digest(224);
-                    case DigestAlgorithm.SHA3_256: return new Sha3Digest(256);
-                    case DigestAlgorithm.SHA3_384: return new Sha3Digest(384);
-                    case DigestAlgorithm.SHA3_512: return new Sha3Digest(512);
-                    case DigestAlgorithm.SHAKE128_256: return new ShakeDigest(128);
-                    case DigestAlgorithm.SHAKE256_512: return new ShakeDigest(256);
-                    case DigestAlgorithm.SM3: return new SM3Digest();
-                    case DigestAlgorithm.TIGER: return new TigerDigest();
-                    case DigestAlgorithm.WHIRLPOOL: return new WhirlpoolDigest();
+                case DigestAlgorithm.BLAKE2B_160: return new Blake2bDigest(160);
+                case DigestAlgorithm.BLAKE2B_256: return new Blake2bDigest(256);
+                case DigestAlgorithm.BLAKE2B_384: return new Blake2bDigest(384);
+                case DigestAlgorithm.BLAKE2B_512: return new Blake2bDigest(512);
+                case DigestAlgorithm.BLAKE2S_128: return new Blake2sDigest(128);
+                case DigestAlgorithm.BLAKE2S_160: return new Blake2sDigest(160);
+                case DigestAlgorithm.BLAKE2S_224: return new Blake2sDigest(224);
+                case DigestAlgorithm.BLAKE2S_256: return new Blake2sDigest(256);
+                case DigestAlgorithm.DSTU7564_256: return new Dstu7564Digest(256);
+                case DigestAlgorithm.DSTU7564_384: return new Dstu7564Digest(384);
+                case DigestAlgorithm.DSTU7564_512: return new Dstu7564Digest(512);
+                case DigestAlgorithm.GOST3411: return new Gost3411Digest();
+                case DigestAlgorithm.GOST3411_2012_256: return new Gost3411_2012_256Digest();
+                case DigestAlgorithm.GOST3411_2012_512: return new Gost3411_2012_512Digest();
+                case DigestAlgorithm.KECCAK_224: return new KeccakDigest(224);
+                case DigestAlgorithm.KECCAK_256: return new KeccakDigest(256);
+                case DigestAlgorithm.KECCAK_288: return new KeccakDigest(288);
+                case DigestAlgorithm.KECCAK_384: return new KeccakDigest(384);
+                case DigestAlgorithm.KECCAK_512: return new KeccakDigest(512);
+                case DigestAlgorithm.MD2: return new MD2Digest();
+                case DigestAlgorithm.MD4: return new MD4Digest();
+                case DigestAlgorithm.MD5: return new MD5Digest();
+                case DigestAlgorithm.NONE: return new NullDigest();
+                case DigestAlgorithm.RIPEMD128: return new RipeMD128Digest();
+                case DigestAlgorithm.RIPEMD160: return new RipeMD160Digest();
+                case DigestAlgorithm.RIPEMD256: return new RipeMD256Digest();
+                case DigestAlgorithm.RIPEMD320: return new RipeMD320Digest();
+                case DigestAlgorithm.SHA_1: return new Sha1Digest();
+                case DigestAlgorithm.SHA_224: return new Sha224Digest();
+                case DigestAlgorithm.SHA_256: return new Sha256Digest();
+                case DigestAlgorithm.SHA_384: return new Sha384Digest();
+                case DigestAlgorithm.SHA_512: return new Sha512Digest();
+                case DigestAlgorithm.SHA_512_224: return new Sha512tDigest(224);
+                case DigestAlgorithm.SHA_512_256: return new Sha512tDigest(256);
+                case DigestAlgorithm.SHA3_224: return new Sha3Digest(224);
+                case DigestAlgorithm.SHA3_256: return new Sha3Digest(256);
+                case DigestAlgorithm.SHA3_384: return new Sha3Digest(384);
+                case DigestAlgorithm.SHA3_512: return new Sha3Digest(512);
+                case DigestAlgorithm.SHAKE128_256: return new ShakeDigest(128);
+                case DigestAlgorithm.SHAKE256_512: return new ShakeDigest(256);
+                case DigestAlgorithm.SM3: return new SM3Digest();
+                case DigestAlgorithm.TIGER: return new TigerDigest();
+                case DigestAlgorithm.WHIRLPOOL: return new WhirlpoolDigest();
                 }
             }
             catch (ArgumentException)
@@ -270,10 +253,9 @@ namespace Org.BouncyCastle.Security
             throw new SecurityUtilityException("Digest " + mechanism + " not recognised.");
         }
 
-        public static string GetAlgorithmName(
-            DerObjectIdentifier oid)
+        public static string GetAlgorithmName(DerObjectIdentifier oid)
         {
-            return (string) algorithms[oid.Id];
+            return CollectionUtilities.GetValueOrNull(Aliases, oid.Id);
         }
 
         public static byte[] CalculateDigest(DerObjectIdentifier id, byte[] input)
@@ -288,17 +270,14 @@ namespace Org.BouncyCastle.Security
             return DoFinal(digest);
         }
 
-        public static byte[] DoFinal(
-            IDigest digest)
+        public static byte[] DoFinal(IDigest digest)
         {
             byte[] b = new byte[digest.GetDigestSize()];
             digest.DoFinal(b, 0);
             return b;
         }
 
-        public static byte[] DoFinal(
-            IDigest	digest,
-            byte[]	input)
+        public static byte[] DoFinal(IDigest digest, byte[] input)
         {
             digest.BlockUpdate(input, 0, input.Length);
             return DoFinal(digest);
diff --git a/crypto/src/security/DotNetUtilities.cs b/crypto/src/security/DotNetUtilities.cs
index 0a83ab88c..d37e27abd 100644
--- a/crypto/src/security/DotNetUtilities.cs
+++ b/crypto/src/security/DotNetUtilities.cs
@@ -17,12 +17,8 @@ namespace Org.BouncyCastle.Security
     /// <summary>
     /// A class containing methods to interface the BouncyCastle world to the .NET Crypto world.
     /// </summary>
-    public sealed class DotNetUtilities
+    public static class DotNetUtilities
     {
-        private DotNetUtilities()
-        {
-        }
-
         /// <summary>
         /// Create an System.Security.Cryptography.X509Certificate from an X509Certificate Structure.
         /// </summary>
diff --git a/crypto/src/security/GeneratorUtilities.cs b/crypto/src/security/GeneratorUtilities.cs
index 8f996bcc6..c48a71f2e 100644
--- a/crypto/src/security/GeneratorUtilities.cs
+++ b/crypto/src/security/GeneratorUtilities.cs
@@ -1,4 +1,5 @@
-using System.Collections;
+using System;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.CryptoPro;
@@ -15,18 +16,18 @@ using Org.BouncyCastle.Asn1.X9;
 using Org.BouncyCastle.Crypto;
 using Org.BouncyCastle.Crypto.Generators;
 using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Collections;
 
 namespace Org.BouncyCastle.Security
 {
-    public sealed class GeneratorUtilities
+    public static class GeneratorUtilities
     {
-        private GeneratorUtilities()
-        {
-        }
-
-        private static readonly IDictionary kgAlgorithms = Platform.CreateHashtable();
-        private static readonly IDictionary kpgAlgorithms = Platform.CreateHashtable();
-        private static readonly IDictionary defaultKeySizes = Platform.CreateHashtable();
+        private static readonly IDictionary<string, string> KgAlgorithms =
+            new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
+        private static readonly IDictionary<string, string> KpgAlgorithms =
+            new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
+        private static readonly IDictionary<string, int> DefaultKeySizes =
+            new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
 
         static GeneratorUtilities()
         {
@@ -263,72 +264,62 @@ namespace Org.BouncyCastle.Security
         {
             foreach (string algorithm in algorithms)
             {
-                defaultKeySizes.Add(algorithm, size);
+                DefaultKeySizes.Add(algorithm, size);
             }
         }
 
-        private static void AddKgAlgorithm(
-            string			canonicalName,
-            params object[] aliases)
+        private static void AddKgAlgorithm(string canonicalName, params object[] aliases)
         {
-            kgAlgorithms[Platform.ToUpperInvariant(canonicalName)] = canonicalName;
+            KgAlgorithms[canonicalName] = canonicalName;
 
             foreach (object alias in aliases)
             {
-                kgAlgorithms[Platform.ToUpperInvariant(alias.ToString())] = canonicalName;
+                KgAlgorithms[alias.ToString()] = canonicalName;
             }
         }
 
-        private static void AddKpgAlgorithm(
-            string			canonicalName,
-            params object[] aliases)
+        private static void AddKpgAlgorithm(string canonicalName, params object[] aliases)
         {
-            kpgAlgorithms[Platform.ToUpperInvariant(canonicalName)] = canonicalName;
+            KpgAlgorithms[canonicalName] = canonicalName;
 
             foreach (object alias in aliases)
             {
-                kpgAlgorithms[Platform.ToUpperInvariant(alias.ToString())] = canonicalName;
+                KpgAlgorithms[alias.ToString()] = canonicalName;
             }
         }
 
-        private static void AddHMacKeyGenerator(
-            string			algorithm,
-            params object[]	aliases)
+        private static void AddHMacKeyGenerator(string algorithm, params object[] aliases)
         {
             string mainName = "HMAC" + algorithm;
 
-            kgAlgorithms[mainName] = mainName;
-            kgAlgorithms["HMAC-" + algorithm] = mainName;
-            kgAlgorithms["HMAC/" + algorithm] = mainName;
+            KgAlgorithms[mainName] = mainName;
+            KgAlgorithms["HMAC-" + algorithm] = mainName;
+            KgAlgorithms["HMAC/" + algorithm] = mainName;
 
             foreach (object alias in aliases)
             {
-                kgAlgorithms[Platform.ToUpperInvariant(alias.ToString())] = mainName;
+                KgAlgorithms[alias.ToString()] = mainName;
             }
         }
 
         // TODO Consider making this public
-        internal static string GetCanonicalKeyGeneratorAlgorithm(
-            string algorithm)
+        internal static string GetCanonicalKeyGeneratorAlgorithm(string algorithm)
         {
-            return (string) kgAlgorithms[Platform.ToUpperInvariant(algorithm)];
+            return CollectionUtilities.GetValueOrNull(KgAlgorithms, algorithm);
         }
 
         // TODO Consider making this public
-        internal static string GetCanonicalKeyPairGeneratorAlgorithm(
-            string algorithm)
+        internal static string GetCanonicalKeyPairGeneratorAlgorithm(string algorithm)
         {
-            return (string)kpgAlgorithms[Platform.ToUpperInvariant(algorithm)];
+            return CollectionUtilities.GetValueOrNull(KpgAlgorithms, algorithm);
         }
 
-        public static CipherKeyGenerator GetKeyGenerator(
-            DerObjectIdentifier oid)
+        public static CipherKeyGenerator GetKeyGenerator(DerObjectIdentifier oid)
         {
             return GetKeyGenerator(oid.Id);
         }
 
-        public static CipherKeyGenerator GetKeyGenerator(
-            string algorithm)
+        public static CipherKeyGenerator GetKeyGenerator(string algorithm)
         {
             string canonicalName = GetCanonicalKeyGeneratorAlgorithm(algorithm);
 
@@ -349,14 +340,12 @@ namespace Org.BouncyCastle.Security
             return new CipherKeyGenerator(defaultKeySize);
         }
 
-        public static IAsymmetricCipherKeyPairGenerator GetKeyPairGenerator(
-            DerObjectIdentifier oid)
+        public static IAsymmetricCipherKeyPairGenerator GetKeyPairGenerator(DerObjectIdentifier oid)
         {
             return GetKeyPairGenerator(oid.Id);
         }
 
-        public static IAsymmetricCipherKeyPairGenerator GetKeyPairGenerator(
-            string algorithm)
+        public static IAsymmetricCipherKeyPairGenerator GetKeyPairGenerator(string algorithm)
         {
             string canonicalName = GetCanonicalKeyPairGeneratorAlgorithm(algorithm);
 
@@ -398,14 +387,12 @@ namespace Org.BouncyCastle.Security
                 + " (" + canonicalName + ") not supported.");
         }
 
-        internal static int GetDefaultKeySize(
-            DerObjectIdentifier oid)
+        internal static int GetDefaultKeySize(DerObjectIdentifier oid)
         {
             return GetDefaultKeySize(oid.Id);
         }
 
-        internal static int GetDefaultKeySize(
-            string algorithm)
+        internal static int GetDefaultKeySize(string algorithm)
         {
             string canonicalName = GetCanonicalKeyGeneratorAlgorithm(algorithm);
 
@@ -420,13 +407,9 @@ namespace Org.BouncyCastle.Security
             return defaultKeySize;
         }
 
-        private static int FindDefaultKeySize(
-            string canonicalName)
+        private static int FindDefaultKeySize(string canonicalName)
         {
-            if (!defaultKeySizes.Contains(canonicalName))
-                return -1;
-
-            return (int)defaultKeySizes[canonicalName];
+            return DefaultKeySizes.TryGetValue(canonicalName, out int keySize) ? keySize : -1;
         }
     }
 }
diff --git a/crypto/src/security/MacUtilities.cs b/crypto/src/security/MacUtilities.cs
index f36fc6ae4..f9f586d29 100644
--- a/crypto/src/security/MacUtilities.cs
+++ b/crypto/src/security/MacUtilities.cs
@@ -1,6 +1,5 @@
 using System;
-using System.Collections;
-using System.Globalization;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.Iana;
@@ -13,118 +12,86 @@ using Org.BouncyCastle.Crypto.Engines;
 using Org.BouncyCastle.Crypto.Macs;
 using Org.BouncyCastle.Crypto.Paddings;
 using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Collections;
 
 namespace Org.BouncyCastle.Security
 {
     /// <remarks>
     ///  Utility class for creating HMac object from their names/Oids
     /// </remarks>
-    public sealed class MacUtilities
+    public static class MacUtilities
     {
-        private MacUtilities()
-        {
-        }
-
-        private static readonly IDictionary algorithms = Platform.CreateHashtable();
-        //private static readonly IDictionary oids = Platform.CreateHashtable();
+        private static readonly IDictionary<string, string> Algorithms =
+            new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
 
         static MacUtilities()
         {
-            algorithms[IanaObjectIdentifiers.HmacMD5.Id] = "HMAC-MD5";
-            algorithms[IanaObjectIdentifiers.HmacRipeMD160.Id] = "HMAC-RIPEMD160";
-            algorithms[IanaObjectIdentifiers.HmacSha1.Id] = "HMAC-SHA1";
-            algorithms[IanaObjectIdentifiers.HmacTiger.Id] = "HMAC-TIGER";
-
-            algorithms[PkcsObjectIdentifiers.IdHmacWithSha1.Id] = "HMAC-SHA1";
-            algorithms[MiscObjectIdentifiers.HMAC_SHA1.Id] = "HMAC-SHA1";
-            algorithms[PkcsObjectIdentifiers.IdHmacWithSha224.Id] = "HMAC-SHA224";
-            algorithms[PkcsObjectIdentifiers.IdHmacWithSha256.Id] = "HMAC-SHA256";
-            algorithms[PkcsObjectIdentifiers.IdHmacWithSha384.Id] = "HMAC-SHA384";
-            algorithms[PkcsObjectIdentifiers.IdHmacWithSha512.Id] = "HMAC-SHA512";
-
-            algorithms[NistObjectIdentifiers.IdHMacWithSha3_224.Id] = "HMAC-SHA3-224";
-            algorithms[NistObjectIdentifiers.IdHMacWithSha3_256.Id] = "HMAC-SHA3-256";
-            algorithms[NistObjectIdentifiers.IdHMacWithSha3_384.Id] = "HMAC-SHA3-384";
-            algorithms[NistObjectIdentifiers.IdHMacWithSha3_512.Id] = "HMAC-SHA3-512";
-
-            algorithms[RosstandartObjectIdentifiers.id_tc26_hmac_gost_3411_12_256.Id] = "HMAC-GOST3411-2012-256";
-            algorithms[RosstandartObjectIdentifiers.id_tc26_hmac_gost_3411_12_512.Id] = "HMAC-GOST3411-2012-512";
+            Algorithms[IanaObjectIdentifiers.HmacMD5.Id] = "HMAC-MD5";
+            Algorithms[IanaObjectIdentifiers.HmacRipeMD160.Id] = "HMAC-RIPEMD160";
+            Algorithms[IanaObjectIdentifiers.HmacSha1.Id] = "HMAC-SHA1";
+            Algorithms[IanaObjectIdentifiers.HmacTiger.Id] = "HMAC-TIGER";
+
+            Algorithms[PkcsObjectIdentifiers.IdHmacWithSha1.Id] = "HMAC-SHA1";
+            Algorithms[MiscObjectIdentifiers.HMAC_SHA1.Id] = "HMAC-SHA1";
+            Algorithms[PkcsObjectIdentifiers.IdHmacWithSha224.Id] = "HMAC-SHA224";
+            Algorithms[PkcsObjectIdentifiers.IdHmacWithSha256.Id] = "HMAC-SHA256";
+            Algorithms[PkcsObjectIdentifiers.IdHmacWithSha384.Id] = "HMAC-SHA384";
+            Algorithms[PkcsObjectIdentifiers.IdHmacWithSha512.Id] = "HMAC-SHA512";
+
+            Algorithms[NistObjectIdentifiers.IdHMacWithSha3_224.Id] = "HMAC-SHA3-224";
+            Algorithms[NistObjectIdentifiers.IdHMacWithSha3_256.Id] = "HMAC-SHA3-256";
+            Algorithms[NistObjectIdentifiers.IdHMacWithSha3_384.Id] = "HMAC-SHA3-384";
+            Algorithms[NistObjectIdentifiers.IdHMacWithSha3_512.Id] = "HMAC-SHA3-512";
+
+            Algorithms[RosstandartObjectIdentifiers.id_tc26_hmac_gost_3411_12_256.Id] = "HMAC-GOST3411-2012-256";
+            Algorithms[RosstandartObjectIdentifiers.id_tc26_hmac_gost_3411_12_512.Id] = "HMAC-GOST3411-2012-512";
 
             // TODO AESMAC?
 
-            algorithms["DES"] = "DESMAC";
-            algorithms["DES/CFB8"] = "DESMAC/CFB8";
-            algorithms["DES64"] = "DESMAC64";
-            algorithms["DESEDE"] = "DESEDEMAC";
-            algorithms[PkcsObjectIdentifiers.DesEde3Cbc.Id] = "DESEDEMAC";
-            algorithms["DESEDE/CFB8"] = "DESEDEMAC/CFB8";
-            algorithms["DESISO9797MAC"] = "DESWITHISO9797";
-            algorithms["DESEDE64"] = "DESEDEMAC64";
-
-            algorithms["DESEDE64WITHISO7816-4PADDING"] = "DESEDEMAC64WITHISO7816-4PADDING";
-            algorithms["DESEDEISO9797ALG1MACWITHISO7816-4PADDING"] = "DESEDEMAC64WITHISO7816-4PADDING";
-            algorithms["DESEDEISO9797ALG1WITHISO7816-4PADDING"] = "DESEDEMAC64WITHISO7816-4PADDING";
-
-            algorithms["ISO9797ALG3"] = "ISO9797ALG3MAC";
-            algorithms["ISO9797ALG3MACWITHISO7816-4PADDING"] = "ISO9797ALG3WITHISO7816-4PADDING";
-
-            algorithms["SKIPJACK"] = "SKIPJACKMAC";
-            algorithms["SKIPJACK/CFB8"] = "SKIPJACKMAC/CFB8";
-            algorithms["IDEA"] = "IDEAMAC";
-            algorithms["IDEA/CFB8"] = "IDEAMAC/CFB8";
-            algorithms["RC2"] = "RC2MAC";
-            algorithms["RC2/CFB8"] = "RC2MAC/CFB8";
-            algorithms["RC5"] = "RC5MAC";
-            algorithms["RC5/CFB8"] = "RC5MAC/CFB8";
-            algorithms["GOST28147"] = "GOST28147MAC";
-            algorithms["VMPC"] = "VMPCMAC";
-            algorithms["VMPC-MAC"] = "VMPCMAC";
-            algorithms["SIPHASH"] = "SIPHASH-2-4";
-
-            algorithms["PBEWITHHMACSHA"] = "PBEWITHHMACSHA1";
-            algorithms["1.3.14.3.2.26"] = "PBEWITHHMACSHA1";
+            Algorithms["DES"] = "DESMAC";
+            Algorithms["DES/CFB8"] = "DESMAC/CFB8";
+            Algorithms["DES64"] = "DESMAC64";
+            Algorithms["DESEDE"] = "DESEDEMAC";
+            Algorithms[PkcsObjectIdentifiers.DesEde3Cbc.Id] = "DESEDEMAC";
+            Algorithms["DESEDE/CFB8"] = "DESEDEMAC/CFB8";
+            Algorithms["DESISO9797MAC"] = "DESWITHISO9797";
+            Algorithms["DESEDE64"] = "DESEDEMAC64";
+
+            Algorithms["DESEDE64WITHISO7816-4PADDING"] = "DESEDEMAC64WITHISO7816-4PADDING";
+            Algorithms["DESEDEISO9797ALG1MACWITHISO7816-4PADDING"] = "DESEDEMAC64WITHISO7816-4PADDING";
+            Algorithms["DESEDEISO9797ALG1WITHISO7816-4PADDING"] = "DESEDEMAC64WITHISO7816-4PADDING";
+
+            Algorithms["ISO9797ALG3"] = "ISO9797ALG3MAC";
+            Algorithms["ISO9797ALG3MACWITHISO7816-4PADDING"] = "ISO9797ALG3WITHISO7816-4PADDING";
+
+            Algorithms["SKIPJACK"] = "SKIPJACKMAC";
+            Algorithms["SKIPJACK/CFB8"] = "SKIPJACKMAC/CFB8";
+            Algorithms["IDEA"] = "IDEAMAC";
+            Algorithms["IDEA/CFB8"] = "IDEAMAC/CFB8";
+            Algorithms["RC2"] = "RC2MAC";
+            Algorithms["RC2/CFB8"] = "RC2MAC/CFB8";
+            Algorithms["RC5"] = "RC5MAC";
+            Algorithms["RC5/CFB8"] = "RC5MAC/CFB8";
+            Algorithms["GOST28147"] = "GOST28147MAC";
+            Algorithms["VMPC"] = "VMPCMAC";
+            Algorithms["VMPC-MAC"] = "VMPCMAC";
+            Algorithms["SIPHASH"] = "SIPHASH-2-4";
+
+            Algorithms["PBEWITHHMACSHA"] = "PBEWITHHMACSHA1";
+            Algorithms["1.3.14.3.2.26"] = "PBEWITHHMACSHA1";
         }
 
-//		/// <summary>
-//		/// Returns a ObjectIdentifier for a given digest mechanism.
-//		/// </summary>
-//		/// <param name="mechanism">A string representation of the digest meanism.</param>
-//		/// <returns>A DerObjectIdentifier, null if the Oid is not available.</returns>
-//		public static DerObjectIdentifier GetObjectIdentifier(
-//			string mechanism)
-//		{
-//			mechanism = (string) algorithms[Platform.ToUpperInvariant(mechanism)];
-//
-//			if (mechanism != null)
-//			{
-//				return (DerObjectIdentifier)oids[mechanism];
-//			}
-//
-//			return null;
-//		}
-
-//		public static ICollection Algorithms
-//		{
-//			get { return oids.Keys; }
-//		}
-
-        public static IMac GetMac(
-            DerObjectIdentifier id)
+        public static IMac GetMac(DerObjectIdentifier id)
         {
             return GetMac(id.Id);
         }
 
-        public static IMac GetMac(
-            string algorithm)
+        public static IMac GetMac(string algorithm)
         {
-            string upper = Platform.ToUpperInvariant(algorithm);
+            if (algorithm == null)
+                throw new ArgumentNullException(nameof(algorithm));
 
-            string mechanism = (string) algorithms[upper];
-
-            if (mechanism == null)
-            {
-                mechanism = upper;
-            }
+            string mechanism = CollectionUtilities.GetValueOrKey(Algorithms, algorithm).ToUpperInvariant();
 
             if (Platform.StartsWith(mechanism, "PBEWITH"))
             {
@@ -238,10 +205,9 @@ namespace Org.BouncyCastle.Security
             throw new SecurityUtilityException("Mac " + mechanism + " not recognised.");
         }
 
-        public static string GetAlgorithmName(
-            DerObjectIdentifier oid)
+        public static string GetAlgorithmName(DerObjectIdentifier oid)
         {
-            return (string) algorithms[oid.Id];
+            return CollectionUtilities.GetValueOrNull(Algorithms, oid.Id);
         }
 
         public static byte[] CalculateMac(string algorithm, ICipherParameters cp, byte[] input)
diff --git a/crypto/src/security/ParameterUtilities.cs b/crypto/src/security/ParameterUtilities.cs
index fdb8d86be..5a407fc9d 100644
--- a/crypto/src/security/ParameterUtilities.cs
+++ b/crypto/src/security/ParameterUtilities.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.CryptoPro;
@@ -12,18 +12,16 @@ using Org.BouncyCastle.Asn1.Oiw;
 using Org.BouncyCastle.Asn1.Pkcs;
 using Org.BouncyCastle.Crypto;
 using Org.BouncyCastle.Crypto.Parameters;
-using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Collections;
 
 namespace Org.BouncyCastle.Security
 {
-    public sealed class ParameterUtilities
+    public static class ParameterUtilities
     {
-        private ParameterUtilities()
-        {
-        }
-
-        private static readonly IDictionary algorithms = Platform.CreateHashtable();
-        private static readonly IDictionary basicIVSizes = Platform.CreateHashtable();
+        private static readonly IDictionary<string, string> Algorithms =
+            new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
+        private static readonly IDictionary<string, int> BasicIVSizes =
+            new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
 
         static ParameterUtilities()
         {
@@ -164,15 +162,13 @@ namespace Org.BouncyCastle.Security
             // "RIJNDAEL", "SKIPJACK", "TWOFISH"
         }
 
-        private static void AddAlgorithm(
-            string			canonicalName,
-            params object[]	aliases)
+        private static void AddAlgorithm(string canonicalName, params object[] aliases)
         {
-            algorithms[canonicalName] = canonicalName;
+            Algorithms[canonicalName] = canonicalName;
 
             foreach (object alias in aliases)
             {
-                algorithms[alias.ToString()] = canonicalName;
+                Algorithms[alias.ToString()] = canonicalName;
             }
         }
 
@@ -180,26 +176,21 @@ namespace Org.BouncyCastle.Security
         {
             foreach (string algorithm in algorithms)
             {
-                basicIVSizes.Add(algorithm, size);
+                BasicIVSizes.Add(algorithm, size);
             }
         }
 
-        public static string GetCanonicalAlgorithmName(
-            string algorithm)
+        public static string GetCanonicalAlgorithmName(string algorithm)
         {
-            return (string) algorithms[Platform.ToUpperInvariant(algorithm)];
+            return CollectionUtilities.GetValueOrNull(Algorithms, algorithm);
         }
 
-        public static KeyParameter CreateKeyParameter(
-            DerObjectIdentifier algOid,
-            byte[]				keyBytes)
+        public static KeyParameter CreateKeyParameter(DerObjectIdentifier algOid, byte[] keyBytes)
         {
             return CreateKeyParameter(algOid.Id, keyBytes, 0, keyBytes.Length);
         }
 
-        public static KeyParameter CreateKeyParameter(
-            string	algorithm,
-            byte[]	keyBytes)
+        public static KeyParameter CreateKeyParameter(string algorithm, byte[] keyBytes)
         {
             return CreateKeyParameter(algorithm, keyBytes, 0, keyBytes.Length);
         }
@@ -220,7 +211,7 @@ namespace Org.BouncyCastle.Security
             int		length)
         {
             if (algorithm == null)
-                throw new ArgumentNullException("algorithm");
+                throw new ArgumentNullException(nameof(algorithm));
 
             string canonical = GetCanonicalAlgorithmName(algorithm);
 
@@ -348,9 +339,7 @@ namespace Org.BouncyCastle.Security
             return cp;
         }
 
-        private static Asn1OctetString CreateIVOctetString(
-            SecureRandom	random,
-            int				ivLength)
+        private static Asn1OctetString CreateIVOctetString(SecureRandom random, int ivLength)
         {
             return new DerOctetString(CreateIV(random, ivLength));
         }
@@ -360,13 +349,9 @@ namespace Org.BouncyCastle.Security
             return SecureRandom.GetNextBytes(random, ivLength);
         }
 
-        private static int FindBasicIVSize(
-            string canonicalName)
+        private static int FindBasicIVSize(string canonicalName)
         {
-            if (!basicIVSizes.Contains(canonicalName))
-                return -1;
-
-            return (int)basicIVSizes[canonicalName];
+            return BasicIVSizes.TryGetValue(canonicalName, out int keySize) ? keySize : -1;
         }
     }
 }
diff --git a/crypto/src/security/PbeUtilities.cs b/crypto/src/security/PbeUtilities.cs
index 622c6dd43..4121ddd7d 100644
--- a/crypto/src/security/PbeUtilities.cs
+++ b/crypto/src/security/PbeUtilities.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.BC;
@@ -10,40 +10,36 @@ using Org.BouncyCastle.Asn1.TeleTrust;
 using Org.BouncyCastle.Asn1.X509;
 using Org.BouncyCastle.Crypto;
 using Org.BouncyCastle.Crypto.Digests;
-using Org.BouncyCastle.Crypto.Engines;
 using Org.BouncyCastle.Crypto.Generators;
-using Org.BouncyCastle.Crypto.Macs;
-using Org.BouncyCastle.Crypto.Modes;
-using Org.BouncyCastle.Crypto.Paddings;
 using Org.BouncyCastle.Crypto.Parameters;
 using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Collections;
 
 namespace Org.BouncyCastle.Security
 {
     /// <summary>
     ///
     /// </summary>
-    public sealed class PbeUtilities
+    public static class PbeUtilities
     {
-        private PbeUtilities()
-        {
-        }
-
         const string Pkcs5S1 = "Pkcs5S1";
         const string Pkcs5S2 = "Pkcs5S2";
         const string Pkcs12 = "Pkcs12";
         const string OpenSsl = "OpenSsl";
 
-        private static readonly IDictionary algorithms = Platform.CreateHashtable();
-        private static readonly IDictionary algorithmType = Platform.CreateHashtable();
-        private static readonly IDictionary oids = Platform.CreateHashtable();
+        private static readonly IDictionary<string, string> Algorithms =
+            new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
+        private static readonly IDictionary<string, string> AlgorithmType =
+            new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
+        private static readonly IDictionary<string, DerObjectIdentifier> Oids =
+            new Dictionary<string, DerObjectIdentifier>(StringComparer.OrdinalIgnoreCase);
 
         static PbeUtilities()
         {
-            algorithms["PKCS5SCHEME1"] = "Pkcs5scheme1";
-            algorithms["PKCS5SCHEME2"] = "Pkcs5scheme2";
-            algorithms["PBKDF2"] = "Pkcs5scheme2";
-            algorithms[PkcsObjectIdentifiers.IdPbeS2.Id] = "Pkcs5scheme2";
+            Algorithms["PKCS5SCHEME1"] = "Pkcs5scheme1";
+            Algorithms["PKCS5SCHEME2"] = "Pkcs5scheme2";
+            Algorithms["PBKDF2"] = "Pkcs5scheme2";
+            Algorithms[PkcsObjectIdentifiers.IdPbeS2.Id] = "Pkcs5scheme2";
 //			algorithms[PkcsObjectIdentifiers.IdPbkdf2.Id] = "Pkcs5scheme2";
 
             // FIXME Add support for these? (see Pkcs8Generator)
@@ -52,155 +48,155 @@ namespace Org.BouncyCastle.Security
 //			algorithms[NistObjectIdentifiers.IdAes192Cbc.Id] = "Pkcs5scheme2";
 //			algorithms[NistObjectIdentifiers.IdAes256Cbc.Id] = "Pkcs5scheme2";
 
-            algorithms["PBEWITHMD2ANDDES-CBC"] = "PBEwithMD2andDES-CBC";
-            algorithms[PkcsObjectIdentifiers.PbeWithMD2AndDesCbc.Id] = "PBEwithMD2andDES-CBC";
-            algorithms["PBEWITHMD2ANDRC2-CBC"] = "PBEwithMD2andRC2-CBC";
-            algorithms[PkcsObjectIdentifiers.PbeWithMD2AndRC2Cbc.Id] = "PBEwithMD2andRC2-CBC";
-            algorithms["PBEWITHMD5ANDDES-CBC"] = "PBEwithMD5andDES-CBC";
-            algorithms[PkcsObjectIdentifiers.PbeWithMD5AndDesCbc.Id] = "PBEwithMD5andDES-CBC";
-            algorithms["PBEWITHMD5ANDRC2-CBC"] = "PBEwithMD5andRC2-CBC";
-            algorithms[PkcsObjectIdentifiers.PbeWithMD5AndRC2Cbc.Id] = "PBEwithMD5andRC2-CBC";
-            algorithms["PBEWITHSHA1ANDDES"] = "PBEwithSHA-1andDES-CBC";
-            algorithms["PBEWITHSHA-1ANDDES"] = "PBEwithSHA-1andDES-CBC";
-            algorithms["PBEWITHSHA1ANDDES-CBC"] = "PBEwithSHA-1andDES-CBC";
-            algorithms["PBEWITHSHA-1ANDDES-CBC"] = "PBEwithSHA-1andDES-CBC";
-            algorithms[PkcsObjectIdentifiers.PbeWithSha1AndDesCbc.Id] = "PBEwithSHA-1andDES-CBC";
-            algorithms["PBEWITHSHA1ANDRC2"] = "PBEwithSHA-1andRC2-CBC";
-            algorithms["PBEWITHSHA-1ANDRC2"] = "PBEwithSHA-1andRC2-CBC";
-            algorithms["PBEWITHSHA1ANDRC2-CBC"] = "PBEwithSHA-1andRC2-CBC";
-            algorithms["PBEWITHSHA-1ANDRC2-CBC"] = "PBEwithSHA-1andRC2-CBC";
-            algorithms[PkcsObjectIdentifiers.PbeWithSha1AndRC2Cbc.Id] = "PBEwithSHA-1andRC2-CBC";
-            algorithms["PKCS12"] = "Pkcs12";
-            algorithms[BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes128_cbc.Id] = "PBEwithSHA-1and128bitAES-CBC-BC";
-            algorithms[BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes192_cbc.Id] = "PBEwithSHA-1and192bitAES-CBC-BC";
-            algorithms[BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes256_cbc.Id] = "PBEwithSHA-1and256bitAES-CBC-BC";
-            algorithms[BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes128_cbc.Id] = "PBEwithSHA-256and128bitAES-CBC-BC";
-            algorithms[BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes192_cbc.Id] = "PBEwithSHA-256and192bitAES-CBC-BC";
-            algorithms[BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes256_cbc.Id] = "PBEwithSHA-256and256bitAES-CBC-BC";
-            algorithms["PBEWITHSHAAND128BITRC4"] = "PBEwithSHA-1and128bitRC4";
-            algorithms["PBEWITHSHA1AND128BITRC4"] = "PBEwithSHA-1and128bitRC4";
-            algorithms["PBEWITHSHA-1AND128BITRC4"] = "PBEwithSHA-1and128bitRC4";
-            algorithms[PkcsObjectIdentifiers.PbeWithShaAnd128BitRC4.Id] = "PBEwithSHA-1and128bitRC4";
-            algorithms["PBEWITHSHAAND40BITRC4"] = "PBEwithSHA-1and40bitRC4";
-            algorithms["PBEWITHSHA1AND40BITRC4"] = "PBEwithSHA-1and40bitRC4";
-            algorithms["PBEWITHSHA-1AND40BITRC4"] = "PBEwithSHA-1and40bitRC4";
-            algorithms[PkcsObjectIdentifiers.PbeWithShaAnd40BitRC4.Id] = "PBEwithSHA-1and40bitRC4";
-            algorithms["PBEWITHSHAAND3-KEYDESEDE-CBC"] = "PBEwithSHA-1and3-keyDESEDE-CBC";
-            algorithms["PBEWITHSHAAND3-KEYTRIPLEDES-CBC"] = "PBEwithSHA-1and3-keyDESEDE-CBC";
-            algorithms["PBEWITHSHA1AND3-KEYDESEDE-CBC"] = "PBEwithSHA-1and3-keyDESEDE-CBC";
-            algorithms["PBEWITHSHA1AND3-KEYTRIPLEDES-CBC"] = "PBEwithSHA-1and3-keyDESEDE-CBC";
-            algorithms["PBEWITHSHA-1AND3-KEYDESEDE-CBC"] = "PBEwithSHA-1and3-keyDESEDE-CBC";
-            algorithms["PBEWITHSHA-1AND3-KEYTRIPLEDES-CBC"] = "PBEwithSHA-1and3-keyDESEDE-CBC";
-            algorithms[PkcsObjectIdentifiers.PbeWithShaAnd3KeyTripleDesCbc.Id] = "PBEwithSHA-1and3-keyDESEDE-CBC";
-            algorithms["PBEWITHSHAAND2-KEYDESEDE-CBC"] = "PBEwithSHA-1and2-keyDESEDE-CBC";
-            algorithms["PBEWITHSHAAND2-KEYTRIPLEDES-CBC"] = "PBEwithSHA-1and2-keyDESEDE-CBC";
-            algorithms["PBEWITHSHA1AND2-KEYDESEDE-CBC"] = "PBEwithSHA-1and2-keyDESEDE-CBC";
-            algorithms["PBEWITHSHA1AND2-KEYTRIPLEDES-CBC"] = "PBEwithSHA-1and2-keyDESEDE-CBC";
-            algorithms["PBEWITHSHA-1AND2-KEYDESEDE-CBC"] = "PBEwithSHA-1and2-keyDESEDE-CBC";
-            algorithms["PBEWITHSHA-1AND2-KEYTRIPLEDES-CBC"] = "PBEwithSHA-1and2-keyDESEDE-CBC";
-            algorithms[PkcsObjectIdentifiers.PbeWithShaAnd2KeyTripleDesCbc.Id] = "PBEwithSHA-1and2-keyDESEDE-CBC";
-            algorithms["PBEWITHSHAAND128BITRC2-CBC"] = "PBEwithSHA-1and128bitRC2-CBC";
-            algorithms["PBEWITHSHA1AND128BITRC2-CBC"] = "PBEwithSHA-1and128bitRC2-CBC";
-            algorithms["PBEWITHSHA-1AND128BITRC2-CBC"] = "PBEwithSHA-1and128bitRC2-CBC";
-            algorithms[PkcsObjectIdentifiers.PbeWithShaAnd128BitRC2Cbc.Id] = "PBEwithSHA-1and128bitRC2-CBC";
-            algorithms["PBEWITHSHAAND40BITRC2-CBC"] = "PBEwithSHA-1and40bitRC2-CBC";
-            algorithms["PBEWITHSHA1AND40BITRC2-CBC"] = "PBEwithSHA-1and40bitRC2-CBC";
-            algorithms["PBEWITHSHA-1AND40BITRC2-CBC"] = "PBEwithSHA-1and40bitRC2-CBC";
-            algorithms[PkcsObjectIdentifiers.PbewithShaAnd40BitRC2Cbc.Id] = "PBEwithSHA-1and40bitRC2-CBC";
-            algorithms["PBEWITHSHAAND128BITAES-CBC-BC"] = "PBEwithSHA-1and128bitAES-CBC-BC";
-            algorithms["PBEWITHSHA1AND128BITAES-CBC-BC"] = "PBEwithSHA-1and128bitAES-CBC-BC";
-            algorithms["PBEWITHSHA-1AND128BITAES-CBC-BC"] = "PBEwithSHA-1and128bitAES-CBC-BC";
-            algorithms["PBEWITHSHAAND192BITAES-CBC-BC"] = "PBEwithSHA-1and192bitAES-CBC-BC";
-            algorithms["PBEWITHSHA1AND192BITAES-CBC-BC"] = "PBEwithSHA-1and192bitAES-CBC-BC";
-            algorithms["PBEWITHSHA-1AND192BITAES-CBC-BC"] = "PBEwithSHA-1and192bitAES-CBC-BC";
-            algorithms["PBEWITHSHAAND256BITAES-CBC-BC"] = "PBEwithSHA-1and256bitAES-CBC-BC";
-            algorithms["PBEWITHSHA1AND256BITAES-CBC-BC"] = "PBEwithSHA-1and256bitAES-CBC-BC";
-            algorithms["PBEWITHSHA-1AND256BITAES-CBC-BC"] = "PBEwithSHA-1and256bitAES-CBC-BC";
-            algorithms["PBEWITHSHA256AND128BITAES-CBC-BC"] = "PBEwithSHA-256and128bitAES-CBC-BC";
-            algorithms["PBEWITHSHA-256AND128BITAES-CBC-BC"] = "PBEwithSHA-256and128bitAES-CBC-BC";
-            algorithms["PBEWITHSHA256AND192BITAES-CBC-BC"] = "PBEwithSHA-256and192bitAES-CBC-BC";
-            algorithms["PBEWITHSHA-256AND192BITAES-CBC-BC"] = "PBEwithSHA-256and192bitAES-CBC-BC";
-            algorithms["PBEWITHSHA256AND256BITAES-CBC-BC"] = "PBEwithSHA-256and256bitAES-CBC-BC";
-            algorithms["PBEWITHSHA-256AND256BITAES-CBC-BC"] = "PBEwithSHA-256and256bitAES-CBC-BC";
-            algorithms["PBEWITHSHAANDIDEA"] = "PBEwithSHA-1andIDEA-CBC";
-            algorithms["PBEWITHSHAANDIDEA-CBC"] = "PBEwithSHA-1andIDEA-CBC";
-            algorithms["PBEWITHSHAANDTWOFISH"] = "PBEwithSHA-1andTWOFISH-CBC";
-            algorithms["PBEWITHSHAANDTWOFISH-CBC"] = "PBEwithSHA-1andTWOFISH-CBC";
-            algorithms["PBEWITHHMACSHA1"] = "PBEwithHmacSHA-1";
-            algorithms["PBEWITHHMACSHA-1"] = "PBEwithHmacSHA-1";
-            algorithms[OiwObjectIdentifiers.IdSha1.Id] = "PBEwithHmacSHA-1";
-            algorithms["PBEWITHHMACSHA224"] = "PBEwithHmacSHA-224";
-            algorithms["PBEWITHHMACSHA-224"] = "PBEwithHmacSHA-224";
-            algorithms[NistObjectIdentifiers.IdSha224.Id] = "PBEwithHmacSHA-224";
-            algorithms["PBEWITHHMACSHA256"] = "PBEwithHmacSHA-256";
-            algorithms["PBEWITHHMACSHA-256"] = "PBEwithHmacSHA-256";
-            algorithms[NistObjectIdentifiers.IdSha256.Id] = "PBEwithHmacSHA-256";
-            algorithms["PBEWITHHMACRIPEMD128"] = "PBEwithHmacRipeMD128";
-            algorithms[TeleTrusTObjectIdentifiers.RipeMD128.Id] = "PBEwithHmacRipeMD128";
-            algorithms["PBEWITHHMACRIPEMD160"] = "PBEwithHmacRipeMD160";
-            algorithms[TeleTrusTObjectIdentifiers.RipeMD160.Id] = "PBEwithHmacRipeMD160";
-            algorithms["PBEWITHHMACRIPEMD256"] = "PBEwithHmacRipeMD256";
-            algorithms[TeleTrusTObjectIdentifiers.RipeMD256.Id] = "PBEwithHmacRipeMD256";
-            algorithms["PBEWITHHMACTIGER"] = "PBEwithHmacTiger";
-
-            algorithms["PBEWITHMD5AND128BITAES-CBC-OPENSSL"] = "PBEwithMD5and128bitAES-CBC-OpenSSL";
-            algorithms["PBEWITHMD5AND192BITAES-CBC-OPENSSL"] = "PBEwithMD5and192bitAES-CBC-OpenSSL";
-            algorithms["PBEWITHMD5AND256BITAES-CBC-OPENSSL"] = "PBEwithMD5and256bitAES-CBC-OpenSSL";
-
-            algorithmType["Pkcs5scheme1"] = Pkcs5S1;
-            algorithmType["Pkcs5scheme2"] = Pkcs5S2;
-            algorithmType["PBEwithMD2andDES-CBC"] = Pkcs5S1;
-            algorithmType["PBEwithMD2andRC2-CBC"] = Pkcs5S1;
-            algorithmType["PBEwithMD5andDES-CBC"] = Pkcs5S1;
-            algorithmType["PBEwithMD5andRC2-CBC"] = Pkcs5S1;
-            algorithmType["PBEwithSHA-1andDES-CBC"] = Pkcs5S1;
-            algorithmType["PBEwithSHA-1andRC2-CBC"] = Pkcs5S1;
-            algorithmType["Pkcs12"] = Pkcs12;
-            algorithmType["PBEwithSHA-1and128bitRC4"] = Pkcs12;
-            algorithmType["PBEwithSHA-1and40bitRC4"] = Pkcs12;
-            algorithmType["PBEwithSHA-1and3-keyDESEDE-CBC"] = Pkcs12;
-            algorithmType["PBEwithSHA-1and2-keyDESEDE-CBC"] = Pkcs12;
-            algorithmType["PBEwithSHA-1and128bitRC2-CBC"] = Pkcs12;
-            algorithmType["PBEwithSHA-1and40bitRC2-CBC"] = Pkcs12;
-            algorithmType["PBEwithSHA-1and128bitAES-CBC-BC"] = Pkcs12;
-            algorithmType["PBEwithSHA-1and192bitAES-CBC-BC"] = Pkcs12;
-            algorithmType["PBEwithSHA-1and256bitAES-CBC-BC"] = Pkcs12;
-            algorithmType["PBEwithSHA-256and128bitAES-CBC-BC"] = Pkcs12;
-            algorithmType["PBEwithSHA-256and192bitAES-CBC-BC"] = Pkcs12;
-            algorithmType["PBEwithSHA-256and256bitAES-CBC-BC"] = Pkcs12;
-            algorithmType["PBEwithSHA-1andIDEA-CBC"] = Pkcs12;
-            algorithmType["PBEwithSHA-1andTWOFISH-CBC"] = Pkcs12;
-            algorithmType["PBEwithHmacSHA-1"] = Pkcs12;
-            algorithmType["PBEwithHmacSHA-224"] = Pkcs12;
-            algorithmType["PBEwithHmacSHA-256"] = Pkcs12;
-            algorithmType["PBEwithHmacRipeMD128"] = Pkcs12;
-            algorithmType["PBEwithHmacRipeMD160"] = Pkcs12;
-            algorithmType["PBEwithHmacRipeMD256"] = Pkcs12;
-            algorithmType["PBEwithHmacTiger"] = Pkcs12;
-
-            algorithmType["PBEwithMD5and128bitAES-CBC-OpenSSL"] = OpenSsl;
-            algorithmType["PBEwithMD5and192bitAES-CBC-OpenSSL"] = OpenSsl;
-            algorithmType["PBEwithMD5and256bitAES-CBC-OpenSSL"] = OpenSsl;
-
-            oids["PBEwithMD2andDES-CBC"] = PkcsObjectIdentifiers.PbeWithMD2AndDesCbc;
-            oids["PBEwithMD2andRC2-CBC"] = PkcsObjectIdentifiers.PbeWithMD2AndRC2Cbc;
-            oids["PBEwithMD5andDES-CBC"] = PkcsObjectIdentifiers.PbeWithMD5AndDesCbc;
-            oids["PBEwithMD5andRC2-CBC"] = PkcsObjectIdentifiers.PbeWithMD5AndRC2Cbc;
-            oids["PBEwithSHA-1andDES-CBC"] = PkcsObjectIdentifiers.PbeWithSha1AndDesCbc;
-            oids["PBEwithSHA-1andRC2-CBC"] = PkcsObjectIdentifiers.PbeWithSha1AndRC2Cbc;
-            oids["PBEwithSHA-1and128bitRC4"] = PkcsObjectIdentifiers.PbeWithShaAnd128BitRC4;
-            oids["PBEwithSHA-1and40bitRC4"] = PkcsObjectIdentifiers.PbeWithShaAnd40BitRC4;
-            oids["PBEwithSHA-1and3-keyDESEDE-CBC"] = PkcsObjectIdentifiers.PbeWithShaAnd3KeyTripleDesCbc;
-            oids["PBEwithSHA-1and2-keyDESEDE-CBC"] = PkcsObjectIdentifiers.PbeWithShaAnd2KeyTripleDesCbc;
-            oids["PBEwithSHA-1and128bitRC2-CBC"] = PkcsObjectIdentifiers.PbeWithShaAnd128BitRC2Cbc;
-            oids["PBEwithSHA-1and40bitRC2-CBC"] = PkcsObjectIdentifiers.PbewithShaAnd40BitRC2Cbc;
-            oids["PBEwithHmacSHA-1"] = OiwObjectIdentifiers.IdSha1;
-            oids["PBEwithHmacSHA-224"] = NistObjectIdentifiers.IdSha224;
-            oids["PBEwithHmacSHA-256"] = NistObjectIdentifiers.IdSha256;
-            oids["PBEwithHmacRipeMD128"] = TeleTrusTObjectIdentifiers.RipeMD128;
-            oids["PBEwithHmacRipeMD160"] = TeleTrusTObjectIdentifiers.RipeMD160;
-            oids["PBEwithHmacRipeMD256"] = TeleTrusTObjectIdentifiers.RipeMD256;
-            oids["Pkcs5scheme2"] = PkcsObjectIdentifiers.IdPbeS2;
+            Algorithms["PBEWITHMD2ANDDES-CBC"] = "PBEwithMD2andDES-CBC";
+            Algorithms[PkcsObjectIdentifiers.PbeWithMD2AndDesCbc.Id] = "PBEwithMD2andDES-CBC";
+            Algorithms["PBEWITHMD2ANDRC2-CBC"] = "PBEwithMD2andRC2-CBC";
+            Algorithms[PkcsObjectIdentifiers.PbeWithMD2AndRC2Cbc.Id] = "PBEwithMD2andRC2-CBC";
+            Algorithms["PBEWITHMD5ANDDES-CBC"] = "PBEwithMD5andDES-CBC";
+            Algorithms[PkcsObjectIdentifiers.PbeWithMD5AndDesCbc.Id] = "PBEwithMD5andDES-CBC";
+            Algorithms["PBEWITHMD5ANDRC2-CBC"] = "PBEwithMD5andRC2-CBC";
+            Algorithms[PkcsObjectIdentifiers.PbeWithMD5AndRC2Cbc.Id] = "PBEwithMD5andRC2-CBC";
+            Algorithms["PBEWITHSHA1ANDDES"] = "PBEwithSHA-1andDES-CBC";
+            Algorithms["PBEWITHSHA-1ANDDES"] = "PBEwithSHA-1andDES-CBC";
+            Algorithms["PBEWITHSHA1ANDDES-CBC"] = "PBEwithSHA-1andDES-CBC";
+            Algorithms["PBEWITHSHA-1ANDDES-CBC"] = "PBEwithSHA-1andDES-CBC";
+            Algorithms[PkcsObjectIdentifiers.PbeWithSha1AndDesCbc.Id] = "PBEwithSHA-1andDES-CBC";
+            Algorithms["PBEWITHSHA1ANDRC2"] = "PBEwithSHA-1andRC2-CBC";
+            Algorithms["PBEWITHSHA-1ANDRC2"] = "PBEwithSHA-1andRC2-CBC";
+            Algorithms["PBEWITHSHA1ANDRC2-CBC"] = "PBEwithSHA-1andRC2-CBC";
+            Algorithms["PBEWITHSHA-1ANDRC2-CBC"] = "PBEwithSHA-1andRC2-CBC";
+            Algorithms[PkcsObjectIdentifiers.PbeWithSha1AndRC2Cbc.Id] = "PBEwithSHA-1andRC2-CBC";
+            Algorithms["PKCS12"] = "Pkcs12";
+            Algorithms[BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes128_cbc.Id] = "PBEwithSHA-1and128bitAES-CBC-BC";
+            Algorithms[BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes192_cbc.Id] = "PBEwithSHA-1and192bitAES-CBC-BC";
+            Algorithms[BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes256_cbc.Id] = "PBEwithSHA-1and256bitAES-CBC-BC";
+            Algorithms[BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes128_cbc.Id] = "PBEwithSHA-256and128bitAES-CBC-BC";
+            Algorithms[BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes192_cbc.Id] = "PBEwithSHA-256and192bitAES-CBC-BC";
+            Algorithms[BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes256_cbc.Id] = "PBEwithSHA-256and256bitAES-CBC-BC";
+            Algorithms["PBEWITHSHAAND128BITRC4"] = "PBEwithSHA-1and128bitRC4";
+            Algorithms["PBEWITHSHA1AND128BITRC4"] = "PBEwithSHA-1and128bitRC4";
+            Algorithms["PBEWITHSHA-1AND128BITRC4"] = "PBEwithSHA-1and128bitRC4";
+            Algorithms[PkcsObjectIdentifiers.PbeWithShaAnd128BitRC4.Id] = "PBEwithSHA-1and128bitRC4";
+            Algorithms["PBEWITHSHAAND40BITRC4"] = "PBEwithSHA-1and40bitRC4";
+            Algorithms["PBEWITHSHA1AND40BITRC4"] = "PBEwithSHA-1and40bitRC4";
+            Algorithms["PBEWITHSHA-1AND40BITRC4"] = "PBEwithSHA-1and40bitRC4";
+            Algorithms[PkcsObjectIdentifiers.PbeWithShaAnd40BitRC4.Id] = "PBEwithSHA-1and40bitRC4";
+            Algorithms["PBEWITHSHAAND3-KEYDESEDE-CBC"] = "PBEwithSHA-1and3-keyDESEDE-CBC";
+            Algorithms["PBEWITHSHAAND3-KEYTRIPLEDES-CBC"] = "PBEwithSHA-1and3-keyDESEDE-CBC";
+            Algorithms["PBEWITHSHA1AND3-KEYDESEDE-CBC"] = "PBEwithSHA-1and3-keyDESEDE-CBC";
+            Algorithms["PBEWITHSHA1AND3-KEYTRIPLEDES-CBC"] = "PBEwithSHA-1and3-keyDESEDE-CBC";
+            Algorithms["PBEWITHSHA-1AND3-KEYDESEDE-CBC"] = "PBEwithSHA-1and3-keyDESEDE-CBC";
+            Algorithms["PBEWITHSHA-1AND3-KEYTRIPLEDES-CBC"] = "PBEwithSHA-1and3-keyDESEDE-CBC";
+            Algorithms[PkcsObjectIdentifiers.PbeWithShaAnd3KeyTripleDesCbc.Id] = "PBEwithSHA-1and3-keyDESEDE-CBC";
+            Algorithms["PBEWITHSHAAND2-KEYDESEDE-CBC"] = "PBEwithSHA-1and2-keyDESEDE-CBC";
+            Algorithms["PBEWITHSHAAND2-KEYTRIPLEDES-CBC"] = "PBEwithSHA-1and2-keyDESEDE-CBC";
+            Algorithms["PBEWITHSHA1AND2-KEYDESEDE-CBC"] = "PBEwithSHA-1and2-keyDESEDE-CBC";
+            Algorithms["PBEWITHSHA1AND2-KEYTRIPLEDES-CBC"] = "PBEwithSHA-1and2-keyDESEDE-CBC";
+            Algorithms["PBEWITHSHA-1AND2-KEYDESEDE-CBC"] = "PBEwithSHA-1and2-keyDESEDE-CBC";
+            Algorithms["PBEWITHSHA-1AND2-KEYTRIPLEDES-CBC"] = "PBEwithSHA-1and2-keyDESEDE-CBC";
+            Algorithms[PkcsObjectIdentifiers.PbeWithShaAnd2KeyTripleDesCbc.Id] = "PBEwithSHA-1and2-keyDESEDE-CBC";
+            Algorithms["PBEWITHSHAAND128BITRC2-CBC"] = "PBEwithSHA-1and128bitRC2-CBC";
+            Algorithms["PBEWITHSHA1AND128BITRC2-CBC"] = "PBEwithSHA-1and128bitRC2-CBC";
+            Algorithms["PBEWITHSHA-1AND128BITRC2-CBC"] = "PBEwithSHA-1and128bitRC2-CBC";
+            Algorithms[PkcsObjectIdentifiers.PbeWithShaAnd128BitRC2Cbc.Id] = "PBEwithSHA-1and128bitRC2-CBC";
+            Algorithms["PBEWITHSHAAND40BITRC2-CBC"] = "PBEwithSHA-1and40bitRC2-CBC";
+            Algorithms["PBEWITHSHA1AND40BITRC2-CBC"] = "PBEwithSHA-1and40bitRC2-CBC";
+            Algorithms["PBEWITHSHA-1AND40BITRC2-CBC"] = "PBEwithSHA-1and40bitRC2-CBC";
+            Algorithms[PkcsObjectIdentifiers.PbewithShaAnd40BitRC2Cbc.Id] = "PBEwithSHA-1and40bitRC2-CBC";
+            Algorithms["PBEWITHSHAAND128BITAES-CBC-BC"] = "PBEwithSHA-1and128bitAES-CBC-BC";
+            Algorithms["PBEWITHSHA1AND128BITAES-CBC-BC"] = "PBEwithSHA-1and128bitAES-CBC-BC";
+            Algorithms["PBEWITHSHA-1AND128BITAES-CBC-BC"] = "PBEwithSHA-1and128bitAES-CBC-BC";
+            Algorithms["PBEWITHSHAAND192BITAES-CBC-BC"] = "PBEwithSHA-1and192bitAES-CBC-BC";
+            Algorithms["PBEWITHSHA1AND192BITAES-CBC-BC"] = "PBEwithSHA-1and192bitAES-CBC-BC";
+            Algorithms["PBEWITHSHA-1AND192BITAES-CBC-BC"] = "PBEwithSHA-1and192bitAES-CBC-BC";
+            Algorithms["PBEWITHSHAAND256BITAES-CBC-BC"] = "PBEwithSHA-1and256bitAES-CBC-BC";
+            Algorithms["PBEWITHSHA1AND256BITAES-CBC-BC"] = "PBEwithSHA-1and256bitAES-CBC-BC";
+            Algorithms["PBEWITHSHA-1AND256BITAES-CBC-BC"] = "PBEwithSHA-1and256bitAES-CBC-BC";
+            Algorithms["PBEWITHSHA256AND128BITAES-CBC-BC"] = "PBEwithSHA-256and128bitAES-CBC-BC";
+            Algorithms["PBEWITHSHA-256AND128BITAES-CBC-BC"] = "PBEwithSHA-256and128bitAES-CBC-BC";
+            Algorithms["PBEWITHSHA256AND192BITAES-CBC-BC"] = "PBEwithSHA-256and192bitAES-CBC-BC";
+            Algorithms["PBEWITHSHA-256AND192BITAES-CBC-BC"] = "PBEwithSHA-256and192bitAES-CBC-BC";
+            Algorithms["PBEWITHSHA256AND256BITAES-CBC-BC"] = "PBEwithSHA-256and256bitAES-CBC-BC";
+            Algorithms["PBEWITHSHA-256AND256BITAES-CBC-BC"] = "PBEwithSHA-256and256bitAES-CBC-BC";
+            Algorithms["PBEWITHSHAANDIDEA"] = "PBEwithSHA-1andIDEA-CBC";
+            Algorithms["PBEWITHSHAANDIDEA-CBC"] = "PBEwithSHA-1andIDEA-CBC";
+            Algorithms["PBEWITHSHAANDTWOFISH"] = "PBEwithSHA-1andTWOFISH-CBC";
+            Algorithms["PBEWITHSHAANDTWOFISH-CBC"] = "PBEwithSHA-1andTWOFISH-CBC";
+            Algorithms["PBEWITHHMACSHA1"] = "PBEwithHmacSHA-1";
+            Algorithms["PBEWITHHMACSHA-1"] = "PBEwithHmacSHA-1";
+            Algorithms[OiwObjectIdentifiers.IdSha1.Id] = "PBEwithHmacSHA-1";
+            Algorithms["PBEWITHHMACSHA224"] = "PBEwithHmacSHA-224";
+            Algorithms["PBEWITHHMACSHA-224"] = "PBEwithHmacSHA-224";
+            Algorithms[NistObjectIdentifiers.IdSha224.Id] = "PBEwithHmacSHA-224";
+            Algorithms["PBEWITHHMACSHA256"] = "PBEwithHmacSHA-256";
+            Algorithms["PBEWITHHMACSHA-256"] = "PBEwithHmacSHA-256";
+            Algorithms[NistObjectIdentifiers.IdSha256.Id] = "PBEwithHmacSHA-256";
+            Algorithms["PBEWITHHMACRIPEMD128"] = "PBEwithHmacRipeMD128";
+            Algorithms[TeleTrusTObjectIdentifiers.RipeMD128.Id] = "PBEwithHmacRipeMD128";
+            Algorithms["PBEWITHHMACRIPEMD160"] = "PBEwithHmacRipeMD160";
+            Algorithms[TeleTrusTObjectIdentifiers.RipeMD160.Id] = "PBEwithHmacRipeMD160";
+            Algorithms["PBEWITHHMACRIPEMD256"] = "PBEwithHmacRipeMD256";
+            Algorithms[TeleTrusTObjectIdentifiers.RipeMD256.Id] = "PBEwithHmacRipeMD256";
+            Algorithms["PBEWITHHMACTIGER"] = "PBEwithHmacTiger";
+
+            Algorithms["PBEWITHMD5AND128BITAES-CBC-OPENSSL"] = "PBEwithMD5and128bitAES-CBC-OpenSSL";
+            Algorithms["PBEWITHMD5AND192BITAES-CBC-OPENSSL"] = "PBEwithMD5and192bitAES-CBC-OpenSSL";
+            Algorithms["PBEWITHMD5AND256BITAES-CBC-OPENSSL"] = "PBEwithMD5and256bitAES-CBC-OpenSSL";
+
+            AlgorithmType["Pkcs5scheme1"] = Pkcs5S1;
+            AlgorithmType["Pkcs5scheme2"] = Pkcs5S2;
+            AlgorithmType["PBEwithMD2andDES-CBC"] = Pkcs5S1;
+            AlgorithmType["PBEwithMD2andRC2-CBC"] = Pkcs5S1;
+            AlgorithmType["PBEwithMD5andDES-CBC"] = Pkcs5S1;
+            AlgorithmType["PBEwithMD5andRC2-CBC"] = Pkcs5S1;
+            AlgorithmType["PBEwithSHA-1andDES-CBC"] = Pkcs5S1;
+            AlgorithmType["PBEwithSHA-1andRC2-CBC"] = Pkcs5S1;
+            AlgorithmType["Pkcs12"] = Pkcs12;
+            AlgorithmType["PBEwithSHA-1and128bitRC4"] = Pkcs12;
+            AlgorithmType["PBEwithSHA-1and40bitRC4"] = Pkcs12;
+            AlgorithmType["PBEwithSHA-1and3-keyDESEDE-CBC"] = Pkcs12;
+            AlgorithmType["PBEwithSHA-1and2-keyDESEDE-CBC"] = Pkcs12;
+            AlgorithmType["PBEwithSHA-1and128bitRC2-CBC"] = Pkcs12;
+            AlgorithmType["PBEwithSHA-1and40bitRC2-CBC"] = Pkcs12;
+            AlgorithmType["PBEwithSHA-1and128bitAES-CBC-BC"] = Pkcs12;
+            AlgorithmType["PBEwithSHA-1and192bitAES-CBC-BC"] = Pkcs12;
+            AlgorithmType["PBEwithSHA-1and256bitAES-CBC-BC"] = Pkcs12;
+            AlgorithmType["PBEwithSHA-256and128bitAES-CBC-BC"] = Pkcs12;
+            AlgorithmType["PBEwithSHA-256and192bitAES-CBC-BC"] = Pkcs12;
+            AlgorithmType["PBEwithSHA-256and256bitAES-CBC-BC"] = Pkcs12;
+            AlgorithmType["PBEwithSHA-1andIDEA-CBC"] = Pkcs12;
+            AlgorithmType["PBEwithSHA-1andTWOFISH-CBC"] = Pkcs12;
+            AlgorithmType["PBEwithHmacSHA-1"] = Pkcs12;
+            AlgorithmType["PBEwithHmacSHA-224"] = Pkcs12;
+            AlgorithmType["PBEwithHmacSHA-256"] = Pkcs12;
+            AlgorithmType["PBEwithHmacRipeMD128"] = Pkcs12;
+            AlgorithmType["PBEwithHmacRipeMD160"] = Pkcs12;
+            AlgorithmType["PBEwithHmacRipeMD256"] = Pkcs12;
+            AlgorithmType["PBEwithHmacTiger"] = Pkcs12;
+
+            AlgorithmType["PBEwithMD5and128bitAES-CBC-OpenSSL"] = OpenSsl;
+            AlgorithmType["PBEwithMD5and192bitAES-CBC-OpenSSL"] = OpenSsl;
+            AlgorithmType["PBEwithMD5and256bitAES-CBC-OpenSSL"] = OpenSsl;
+
+            Oids["PBEwithMD2andDES-CBC"] = PkcsObjectIdentifiers.PbeWithMD2AndDesCbc;
+            Oids["PBEwithMD2andRC2-CBC"] = PkcsObjectIdentifiers.PbeWithMD2AndRC2Cbc;
+            Oids["PBEwithMD5andDES-CBC"] = PkcsObjectIdentifiers.PbeWithMD5AndDesCbc;
+            Oids["PBEwithMD5andRC2-CBC"] = PkcsObjectIdentifiers.PbeWithMD5AndRC2Cbc;
+            Oids["PBEwithSHA-1andDES-CBC"] = PkcsObjectIdentifiers.PbeWithSha1AndDesCbc;
+            Oids["PBEwithSHA-1andRC2-CBC"] = PkcsObjectIdentifiers.PbeWithSha1AndRC2Cbc;
+            Oids["PBEwithSHA-1and128bitRC4"] = PkcsObjectIdentifiers.PbeWithShaAnd128BitRC4;
+            Oids["PBEwithSHA-1and40bitRC4"] = PkcsObjectIdentifiers.PbeWithShaAnd40BitRC4;
+            Oids["PBEwithSHA-1and3-keyDESEDE-CBC"] = PkcsObjectIdentifiers.PbeWithShaAnd3KeyTripleDesCbc;
+            Oids["PBEwithSHA-1and2-keyDESEDE-CBC"] = PkcsObjectIdentifiers.PbeWithShaAnd2KeyTripleDesCbc;
+            Oids["PBEwithSHA-1and128bitRC2-CBC"] = PkcsObjectIdentifiers.PbeWithShaAnd128BitRC2Cbc;
+            Oids["PBEwithSHA-1and40bitRC2-CBC"] = PkcsObjectIdentifiers.PbewithShaAnd40BitRC2Cbc;
+            Oids["PBEwithHmacSHA-1"] = OiwObjectIdentifiers.IdSha1;
+            Oids["PBEwithHmacSHA-224"] = NistObjectIdentifiers.IdSha224;
+            Oids["PBEwithHmacSHA-256"] = NistObjectIdentifiers.IdSha256;
+            Oids["PBEwithHmacRipeMD128"] = TeleTrusTObjectIdentifiers.RipeMD128;
+            Oids["PBEwithHmacRipeMD160"] = TeleTrusTObjectIdentifiers.RipeMD160;
+            Oids["PBEwithHmacRipeMD256"] = TeleTrusTObjectIdentifiers.RipeMD256;
+            Oids["Pkcs5scheme2"] = PkcsObjectIdentifiers.IdPbeS2;
         }
 
         static PbeParametersGenerator MakePbeGenerator(
@@ -242,60 +238,65 @@ namespace Org.BouncyCastle.Security
         /// </summary>
         /// <param name="mechanism">A string representation of the encoding.</param>
         /// <returns>A DerObjectIdentifier, null if the Oid is not available.</returns>
-        public static DerObjectIdentifier GetObjectIdentifier(
-            string mechanism)
+        public static DerObjectIdentifier GetObjectIdentifier(string mechanism)
         {
-            mechanism = (string) algorithms[Platform.ToUpperInvariant(mechanism)];
-            if (mechanism != null)
-            {
-                return (DerObjectIdentifier)oids[mechanism];
-            }
-            return null;
-        }
+            if (!Algorithms.TryGetValue(mechanism, out var algorithm))
+                return null;
 
-        public static ICollection Algorithms
-        {
-            get { return oids.Keys; }
+            return CollectionUtilities.GetValueOrNull(Oids, algorithm);
         }
 
-        public static bool IsPkcs12(
-            string algorithm)
+        //public static ICollection Algorithms
+        //{
+        //    get { return oids.Keys; }
+        //}
+
+        public static bool IsPkcs12(string algorithm)
         {
-            string mechanism = (string)algorithms[Platform.ToUpperInvariant(algorithm)];
+            if (!Algorithms.TryGetValue(algorithm, out var mechanism))
+                return false;
+            if (!AlgorithmType.TryGetValue(mechanism, out var algorithmType))
+                return false;
 
-            return mechanism != null && Pkcs12.Equals(algorithmType[mechanism]);
+            return Pkcs12.Equals(algorithmType);
         }
 
-        public static bool IsPkcs5Scheme1(
-            string algorithm)
+        public static bool IsPkcs5Scheme1(string algorithm)
         {
-            string mechanism = (string)algorithms[Platform.ToUpperInvariant(algorithm)];
+            if (!Algorithms.TryGetValue(algorithm, out var mechanism))
+                return false;
+            if (!AlgorithmType.TryGetValue(mechanism, out var algorithmType))
+                return false;
 
-            return mechanism != null && Pkcs5S1.Equals(algorithmType[mechanism]);
+            return Pkcs5S1.Equals(algorithmType);
         }
 
-        public static bool IsPkcs5Scheme2(
-            string algorithm)
+        public static bool IsPkcs5Scheme2(string algorithm)
         {
-            string mechanism = (string)algorithms[Platform.ToUpperInvariant(algorithm)];
+            if (!Algorithms.TryGetValue(algorithm, out var mechanism))
+                return false;
+            if (!AlgorithmType.TryGetValue(mechanism, out var algorithmType))
+                return false;
 
-            return mechanism != null && Pkcs5S2.Equals(algorithmType[mechanism]);
+            return Pkcs5S2.Equals(algorithmType);
         }
 
-        public static bool IsOpenSsl(
-            string algorithm)
+        public static bool IsOpenSsl(string algorithm)
         {
-            string mechanism = (string)algorithms[Platform.ToUpperInvariant(algorithm)];
+            if (!Algorithms.TryGetValue(algorithm, out var mechanism))
+                return false;
+            if (!AlgorithmType.TryGetValue(mechanism, out var algorithmType))
+                return false;
 
-            return mechanism != null && OpenSsl.Equals(algorithmType[mechanism]);
+            return OpenSsl.Equals(algorithmType);
         }
 
-        public static bool IsPbeAlgorithm(
-            string algorithm)
+        public static bool IsPbeAlgorithm(string algorithm)
         {
-            string mechanism = (string)algorithms[Platform.ToUpperInvariant(algorithm)];
+            if (!Algorithms.TryGetValue(algorithm, out var mechanism))
+                return false;
 
-            return mechanism != null && algorithmType[mechanism] != null;
+            return AlgorithmType.ContainsKey(mechanism);
         }
 
         public static Asn1Encodable GenerateAlgorithmParameters(
@@ -400,7 +401,7 @@ namespace Org.BouncyCastle.Security
             bool			wrongPkcs12Zero,
             Asn1Encodable   pbeParameters)
         {
-            string mechanism = (string)algorithms[Platform.ToUpperInvariant(algorithm)];
+            string mechanism = CollectionUtilities.GetValueOrNull(Algorithms, algorithm);
 
             byte[] keyBytes = null;
             byte[] salt = null;
@@ -457,7 +458,7 @@ namespace Org.BouncyCastle.Security
                     :	GeneratorUtilities.GetDefaultKeySize(encOid);
 
                 PbeParametersGenerator gen = MakePbeGenerator(
-                    (string)algorithmType[mechanism], digest, keyBytes, salt, iterationCount);
+                    AlgorithmType[mechanism], digest, keyBytes, salt, iterationCount);
 
                 parameters = gen.GenerateDerivedParameters(encOid.Id, keyLength);
 
@@ -477,7 +478,7 @@ namespace Org.BouncyCastle.Security
             else if (Platform.StartsWith(mechanism, "PBEwithSHA-1"))
             {
                 PbeParametersGenerator generator = MakePbeGenerator(
-                    (string) algorithmType[mechanism], new Sha1Digest(), keyBytes, salt, iterationCount);
+                    AlgorithmType[mechanism], new Sha1Digest(), keyBytes, salt, iterationCount);
 
                 if (mechanism.Equals("PBEwithSHA-1and128bitAES-CBC-BC"))
                 {
@@ -527,7 +528,7 @@ namespace Org.BouncyCastle.Security
             else if (Platform.StartsWith(mechanism, "PBEwithSHA-256"))
             {
                 PbeParametersGenerator generator = MakePbeGenerator(
-                    (string) algorithmType[mechanism], new Sha256Digest(), keyBytes, salt, iterationCount);
+                    AlgorithmType[mechanism], new Sha256Digest(), keyBytes, salt, iterationCount);
 
                 if (mechanism.Equals("PBEwithSHA-256and128bitAES-CBC-BC"))
                 {
@@ -545,7 +546,7 @@ namespace Org.BouncyCastle.Security
             else if (Platform.StartsWith(mechanism, "PBEwithMD5"))
             {
                 PbeParametersGenerator generator = MakePbeGenerator(
-                    (string)algorithmType[mechanism], new MD5Digest(), keyBytes, salt, iterationCount);
+                    AlgorithmType[mechanism], new MD5Digest(), keyBytes, salt, iterationCount);
 
                 if (mechanism.Equals("PBEwithMD5andDES-CBC"))
                 {
@@ -571,7 +572,7 @@ namespace Org.BouncyCastle.Security
             else if (Platform.StartsWith(mechanism, "PBEwithMD2"))
             {
                 PbeParametersGenerator generator = MakePbeGenerator(
-                    (string)algorithmType[mechanism], new MD2Digest(), keyBytes, salt, iterationCount);
+                    AlgorithmType[mechanism], new MD2Digest(), keyBytes, salt, iterationCount);
                 if (mechanism.Equals("PBEwithMD2andDES-CBC"))
                 {
                     parameters = generator.GenerateDerivedParameters("DES", 64, 64);
@@ -587,7 +588,7 @@ namespace Org.BouncyCastle.Security
                 IDigest digest = DigestUtilities.GetDigest(digestName);
 
                 PbeParametersGenerator generator = MakePbeGenerator(
-                    (string) algorithmType[mechanism], digest, keyBytes, salt, iterationCount);
+                    AlgorithmType[mechanism], digest, keyBytes, salt, iterationCount);
 
                 int bitLen = digest.GetDigestSize() * 8;
                 parameters = generator.GenerateDerivedMacParameters(bitLen);
@@ -619,10 +620,9 @@ namespace Org.BouncyCastle.Security
             return CreateEngine(algorithm);
         }
 
-        public static object CreateEngine(
-            string algorithm)
+        public static object CreateEngine(string algorithm)
         {
-            string mechanism = (string)algorithms[Platform.ToUpperInvariant(algorithm)];
+            string mechanism = CollectionUtilities.GetValueOrNull(Algorithms, algorithm);
 
             if (Platform.StartsWith(mechanism, "PBEwithHmac"))
             {
@@ -665,10 +665,9 @@ namespace Org.BouncyCastle.Security
             return null;
         }
 
-        public static string GetEncodingName(
-            DerObjectIdentifier oid)
+        public static string GetEncodingName(DerObjectIdentifier oid)
         {
-            return (string) algorithms[oid.Id];
+            return CollectionUtilities.GetValueOrNull(Algorithms, oid.Id);
         }
 
         private static ICipherParameters FixDesParity(string mechanism, ICipherParameters parameters)
diff --git a/crypto/src/security/PrivateKeyFactory.cs b/crypto/src/security/PrivateKeyFactory.cs
index 93f8a2260..3c57297fe 100644
--- a/crypto/src/security/PrivateKeyFactory.cs
+++ b/crypto/src/security/PrivateKeyFactory.cs
@@ -1,7 +1,5 @@
 using System;
-using System.Collections;
 using System.IO;
-using System.Text;
 
 using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.CryptoPro;
diff --git a/crypto/src/security/PublicKeyFactory.cs b/crypto/src/security/PublicKeyFactory.cs
index 65baf003c..49ad49dd0 100644
--- a/crypto/src/security/PublicKeyFactory.cs
+++ b/crypto/src/security/PublicKeyFactory.cs
@@ -1,7 +1,5 @@
 using System;
-using System.Collections;
 using System.IO;
-using System.Text;
 
 using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.CryptoPro;
@@ -9,7 +7,6 @@ using Org.BouncyCastle.Asn1.EdEC;
 using Org.BouncyCastle.Asn1.Oiw;
 using Org.BouncyCastle.Asn1.Pkcs;
 using Org.BouncyCastle.Asn1.Rosstandart;
-using Org.BouncyCastle.Asn1.Sec;
 using Org.BouncyCastle.Asn1.X509;
 using Org.BouncyCastle.Asn1.X9;
 using Org.BouncyCastle.Crypto;
@@ -18,7 +15,6 @@ using Org.BouncyCastle.Crypto.Parameters;
 using Org.BouncyCastle.Math;
 using Org.BouncyCastle.Math.EC;
 using Org.BouncyCastle.Utilities;
-using Org.BouncyCastle.Utilities.Encoders;
 
 namespace Org.BouncyCastle.Security
 {
diff --git a/crypto/src/security/SecureRandom.cs b/crypto/src/security/SecureRandom.cs
index eb5d69618..e8cac56f5 100644
--- a/crypto/src/security/SecureRandom.cs
+++ b/crypto/src/security/SecureRandom.cs
@@ -62,15 +62,16 @@ namespace Org.BouncyCastle.Security
         /// <param name="autoSeed">If true, the instance will be auto-seeded.</param>
         public static SecureRandom GetInstance(string algorithm, bool autoSeed)
         {
-            string upper = Platform.ToUpperInvariant(algorithm);
-            if (Platform.EndsWith(upper, "PRNG"))
+            if (algorithm == null)
+                throw new ArgumentNullException(nameof(algorithm));
+
+            if (algorithm.EndsWith("PRNG", StringComparison.OrdinalIgnoreCase))
             {
-                string digestName = upper.Substring(0, upper.Length - "PRNG".Length);
+                string digestName = algorithm.Substring(0, algorithm.Length - "PRNG".Length);
+
                 DigestRandomGenerator prng = CreatePrng(digestName, autoSeed);
                 if (prng != null)
-                {
                     return new SecureRandom(prng);
-                }
             }
 
             throw new ArgumentException("Unrecognised PRNG algorithm: " + algorithm, "algorithm");
diff --git a/crypto/src/security/SignerUtilities.cs b/crypto/src/security/SignerUtilities.cs
index b3a49dea8..e42e217cc 100644
--- a/crypto/src/security/SignerUtilities.cs
+++ b/crypto/src/security/SignerUtilities.cs
@@ -1,6 +1,5 @@
 using System;
-using System.Collections;
-using System.IO;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.Bsi;
@@ -14,439 +13,437 @@ using Org.BouncyCastle.Asn1.Pkcs;
 using Org.BouncyCastle.Asn1.TeleTrust;
 using Org.BouncyCastle.Asn1.X509;
 using Org.BouncyCastle.Asn1.X9;
-using Org.BouncyCastle.Security;
 using Org.BouncyCastle.Crypto.Digests;
 using Org.BouncyCastle.Crypto;
 using Org.BouncyCastle.Crypto.Engines;
 using Org.BouncyCastle.Crypto.Signers;
 using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Collections;
 
 namespace Org.BouncyCastle.Security
 {
     /// <summary>
     ///  Signer Utility class contains methods that can not be specifically grouped into other classes.
     /// </summary>
-    public sealed class SignerUtilities
+    public static class SignerUtilities
     {
-        private SignerUtilities()
-        {
-        }
-
-        internal static readonly IDictionary algorithms = Platform.CreateHashtable();
-        internal static readonly IDictionary oids = Platform.CreateHashtable();
+        internal static readonly IDictionary<string, string> AlgorithmMap =
+            new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
+        internal static readonly IDictionary<string, DerObjectIdentifier> Oids =
+            new Dictionary<string, DerObjectIdentifier>(StringComparer.OrdinalIgnoreCase);
 
         static SignerUtilities()
         {
-            algorithms["MD2WITHRSA"] = "MD2withRSA";
-            algorithms["MD2WITHRSAENCRYPTION"] = "MD2withRSA";
-            algorithms[PkcsObjectIdentifiers.MD2WithRsaEncryption.Id] = "MD2withRSA";
-
-            algorithms["MD4WITHRSA"] = "MD4withRSA";
-            algorithms["MD4WITHRSAENCRYPTION"] = "MD4withRSA";
-            algorithms[PkcsObjectIdentifiers.MD4WithRsaEncryption.Id] = "MD4withRSA";
-            algorithms[OiwObjectIdentifiers.MD4WithRsa.Id] = "MD4withRSA";
-			algorithms[OiwObjectIdentifiers.MD4WithRsaEncryption.Id] = "MD4withRSA";
-
-			algorithms["MD5WITHRSA"] = "MD5withRSA";
-            algorithms["MD5WITHRSAENCRYPTION"] = "MD5withRSA";
-            algorithms[PkcsObjectIdentifiers.MD5WithRsaEncryption.Id] = "MD5withRSA";
-            algorithms[OiwObjectIdentifiers.MD5WithRsa.Id] = "MD5withRSA";
-
-            algorithms["SHA1WITHRSA"] = "SHA-1withRSA";
-            algorithms["SHA-1WITHRSA"] = "SHA-1withRSA";
-            algorithms["SHA1WITHRSAENCRYPTION"] = "SHA-1withRSA";
-            algorithms["SHA-1WITHRSAENCRYPTION"] = "SHA-1withRSA";
-            algorithms[PkcsObjectIdentifiers.Sha1WithRsaEncryption.Id] = "SHA-1withRSA";
-            algorithms[OiwObjectIdentifiers.Sha1WithRsa.Id] = "SHA-1withRSA";
-
-            algorithms["SHA224WITHRSA"] = "SHA-224withRSA";
-            algorithms["SHA-224WITHRSA"] = "SHA-224withRSA";
-            algorithms["SHA224WITHRSAENCRYPTION"] = "SHA-224withRSA";
-            algorithms["SHA-224WITHRSAENCRYPTION"] = "SHA-224withRSA";
-            algorithms[PkcsObjectIdentifiers.Sha224WithRsaEncryption.Id] = "SHA-224withRSA";
-
-            algorithms["SHA256WITHRSA"] = "SHA-256withRSA";
-            algorithms["SHA-256WITHRSA"] = "SHA-256withRSA";
-            algorithms["SHA256WITHRSAENCRYPTION"] = "SHA-256withRSA";
-            algorithms["SHA-256WITHRSAENCRYPTION"] = "SHA-256withRSA";
-            algorithms[PkcsObjectIdentifiers.Sha256WithRsaEncryption.Id] = "SHA-256withRSA";
-
-            algorithms["SHA384WITHRSA"] = "SHA-384withRSA";
-            algorithms["SHA-384WITHRSA"] = "SHA-384withRSA";
-            algorithms["SHA384WITHRSAENCRYPTION"] = "SHA-384withRSA";
-            algorithms["SHA-384WITHRSAENCRYPTION"] = "SHA-384withRSA";
-            algorithms[PkcsObjectIdentifiers.Sha384WithRsaEncryption.Id] = "SHA-384withRSA";
-
-            algorithms["SHA512WITHRSA"] = "SHA-512withRSA";
-            algorithms["SHA-512WITHRSA"] = "SHA-512withRSA";
-            algorithms["SHA512WITHRSAENCRYPTION"] = "SHA-512withRSA";
-            algorithms["SHA-512WITHRSAENCRYPTION"] = "SHA-512withRSA";
-            algorithms[PkcsObjectIdentifiers.Sha512WithRsaEncryption.Id] = "SHA-512withRSA";
-
-            algorithms["SHA512(224)WITHRSA"] = "SHA-512(224)withRSA";
-            algorithms["SHA-512(224)WITHRSA"] = "SHA-512(224)withRSA";
-            algorithms["SHA512(224)WITHRSAENCRYPTION"] = "SHA-512(224)withRSA";
-            algorithms["SHA-512(224)WITHRSAENCRYPTION"] = "SHA-512(224)withRSA";
-            algorithms[PkcsObjectIdentifiers.Sha512_224WithRSAEncryption.Id] = "SHA-512(224)withRSA";
-
-            algorithms["SHA512(256)WITHRSA"] = "SHA-512(256)withRSA";
-            algorithms["SHA-512(256)WITHRSA"] = "SHA-512(256)withRSA";
-            algorithms["SHA512(256)WITHRSAENCRYPTION"] = "SHA-512(256)withRSA";
-            algorithms["SHA-512(256)WITHRSAENCRYPTION"] = "SHA-512(256)withRSA";
-            algorithms[PkcsObjectIdentifiers.Sha512_256WithRSAEncryption.Id] = "SHA-512(256)withRSA";
-
-            algorithms["SHA3-224WITHRSA"] = "SHA3-224withRSA";
-            algorithms["SHA3-224WITHRSAENCRYPTION"] = "SHA3-224withRSA";
-            algorithms[NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_224.Id] = "SHA3-224withRSA";
-            algorithms["SHA3-256WITHRSA"] = "SHA3-256withRSA";
-            algorithms["SHA3-256WITHRSAENCRYPTION"] = "SHA3-256withRSA";
-            algorithms[NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_256.Id] = "SHA3-256withRSA";
-            algorithms["SHA3-384WITHRSA"] = "SHA3-384withRSA";
-            algorithms["SHA3-384WITHRSAENCRYPTION"] = "SHA3-384withRSA";
-            algorithms[NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_384.Id] = "SHA3-384withRSA";
-            algorithms["SHA3-512WITHRSA"] = "SHA3-512withRSA";
-            algorithms["SHA3-512WITHRSAENCRYPTION"] = "SHA3-512withRSA";
-            algorithms[NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_512.Id] = "SHA3-512withRSA";
-
-            algorithms["PSSWITHRSA"] = "PSSwithRSA";
-            algorithms["RSASSA-PSS"] = "PSSwithRSA";
-            algorithms[PkcsObjectIdentifiers.IdRsassaPss.Id] = "PSSwithRSA";
-            algorithms["RSAPSS"] = "PSSwithRSA";
-
-            algorithms["SHA1WITHRSAANDMGF1"] = "SHA-1withRSAandMGF1";
-            algorithms["SHA-1WITHRSAANDMGF1"] = "SHA-1withRSAandMGF1";
-            algorithms["SHA1WITHRSA/PSS"] = "SHA-1withRSAandMGF1";
-            algorithms["SHA-1WITHRSA/PSS"] = "SHA-1withRSAandMGF1";
-            algorithms["SHA1WITHRSASSA-PSS"] = "SHA-1withRSAandMGF1";
-            algorithms["SHA-1WITHRSASSA-PSS"] = "SHA-1withRSAandMGF1";
-
-            algorithms["SHA224WITHRSAANDMGF1"] = "SHA-224withRSAandMGF1";
-            algorithms["SHA-224WITHRSAANDMGF1"] = "SHA-224withRSAandMGF1";
-            algorithms["SHA224WITHRSA/PSS"] = "SHA-224withRSAandMGF1";
-            algorithms["SHA-224WITHRSA/PSS"] = "SHA-224withRSAandMGF1";
-            algorithms["SHA224WITHRSASSA-PSS"] = "SHA-224withRSAandMGF1";
-            algorithms["SHA-224WITHRSASSA-PSS"] = "SHA-224withRSAandMGF1";
-
-            algorithms["SHA256WITHRSAANDMGF1"] = "SHA-256withRSAandMGF1";
-            algorithms["SHA-256WITHRSAANDMGF1"] = "SHA-256withRSAandMGF1";
-            algorithms["SHA256WITHRSA/PSS"] = "SHA-256withRSAandMGF1";
-            algorithms["SHA-256WITHRSA/PSS"] = "SHA-256withRSAandMGF1";
-            algorithms["SHA256WITHRSASSA-PSS"] = "SHA-256withRSAandMGF1";
-            algorithms["SHA-256WITHRSASSA-PSS"] = "SHA-256withRSAandMGF1";
-
-            algorithms["SHA384WITHRSAANDMGF1"] = "SHA-384withRSAandMGF1";
-            algorithms["SHA-384WITHRSAANDMGF1"] = "SHA-384withRSAandMGF1";
-            algorithms["SHA384WITHRSA/PSS"] = "SHA-384withRSAandMGF1";
-            algorithms["SHA-384WITHRSA/PSS"] = "SHA-384withRSAandMGF1";
-            algorithms["SHA384WITHRSASSA-PSS"] = "SHA-384withRSAandMGF1";
-            algorithms["SHA-384WITHRSASSA-PSS"] = "SHA-384withRSAandMGF1";
-
-            algorithms["SHA512WITHRSAANDMGF1"] = "SHA-512withRSAandMGF1";
-            algorithms["SHA-512WITHRSAANDMGF1"] = "SHA-512withRSAandMGF1";
-            algorithms["SHA512WITHRSA/PSS"] = "SHA-512withRSAandMGF1";
-            algorithms["SHA-512WITHRSA/PSS"] = "SHA-512withRSAandMGF1";
-            algorithms["SHA512WITHRSASSA-PSS"] = "SHA-512withRSAandMGF1";
-            algorithms["SHA-512WITHRSASSA-PSS"] = "SHA-512withRSAandMGF1";
-
-            algorithms["RIPEMD128WITHRSA"] = "RIPEMD128withRSA";
-            algorithms["RIPEMD128WITHRSAENCRYPTION"] = "RIPEMD128withRSA";
-            algorithms[TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128.Id] = "RIPEMD128withRSA";
-
-            algorithms["RIPEMD160WITHRSA"] = "RIPEMD160withRSA";
-            algorithms["RIPEMD160WITHRSAENCRYPTION"] = "RIPEMD160withRSA";
-            algorithms[TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160.Id] = "RIPEMD160withRSA";
-
-            algorithms["RIPEMD256WITHRSA"] = "RIPEMD256withRSA";
-            algorithms["RIPEMD256WITHRSAENCRYPTION"] = "RIPEMD256withRSA";
-            algorithms[TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256.Id] = "RIPEMD256withRSA";
-
-            algorithms["NONEWITHRSA"] = "RSA";
-            algorithms["RSAWITHNONE"] = "RSA";
-            algorithms["RAWRSA"] = "RSA";
-
-            algorithms["RAWRSAPSS"] = "RAWRSASSA-PSS";
-            algorithms["NONEWITHRSAPSS"] = "RAWRSASSA-PSS";
-            algorithms["NONEWITHRSASSA-PSS"] = "RAWRSASSA-PSS";
-
-            algorithms["NONEWITHDSA"] = "NONEwithDSA";
-            algorithms["DSAWITHNONE"] = "NONEwithDSA";
-            algorithms["RAWDSA"] = "NONEwithDSA";
-
-            algorithms["DSA"] = "SHA-1withDSA";
-            algorithms["DSAWITHSHA1"] = "SHA-1withDSA";
-            algorithms["DSAWITHSHA-1"] = "SHA-1withDSA";
-            algorithms["SHA/DSA"] = "SHA-1withDSA";
-            algorithms["SHA1/DSA"] = "SHA-1withDSA";
-            algorithms["SHA-1/DSA"] = "SHA-1withDSA";
-            algorithms["SHA1WITHDSA"] = "SHA-1withDSA";
-            algorithms["SHA-1WITHDSA"] = "SHA-1withDSA";
-            algorithms[X9ObjectIdentifiers.IdDsaWithSha1.Id] = "SHA-1withDSA";
-            algorithms[OiwObjectIdentifiers.DsaWithSha1.Id] = "SHA-1withDSA";
-
-            algorithms["DSAWITHSHA224"] = "SHA-224withDSA";
-            algorithms["DSAWITHSHA-224"] = "SHA-224withDSA";
-            algorithms["SHA224/DSA"] = "SHA-224withDSA";
-            algorithms["SHA-224/DSA"] = "SHA-224withDSA";
-            algorithms["SHA224WITHDSA"] = "SHA-224withDSA";
-            algorithms["SHA-224WITHDSA"] = "SHA-224withDSA";
-            algorithms[NistObjectIdentifiers.DsaWithSha224.Id] = "SHA-224withDSA";
-
-            algorithms["DSAWITHSHA256"] = "SHA-256withDSA";
-            algorithms["DSAWITHSHA-256"] = "SHA-256withDSA";
-            algorithms["SHA256/DSA"] = "SHA-256withDSA";
-            algorithms["SHA-256/DSA"] = "SHA-256withDSA";
-            algorithms["SHA256WITHDSA"] = "SHA-256withDSA";
-            algorithms["SHA-256WITHDSA"] = "SHA-256withDSA";
-            algorithms[NistObjectIdentifiers.DsaWithSha256.Id] = "SHA-256withDSA";
-
-            algorithms["DSAWITHSHA384"] = "SHA-384withDSA";
-            algorithms["DSAWITHSHA-384"] = "SHA-384withDSA";
-            algorithms["SHA384/DSA"] = "SHA-384withDSA";
-            algorithms["SHA-384/DSA"] = "SHA-384withDSA";
-            algorithms["SHA384WITHDSA"] = "SHA-384withDSA";
-            algorithms["SHA-384WITHDSA"] = "SHA-384withDSA";
-            algorithms[NistObjectIdentifiers.DsaWithSha384.Id] = "SHA-384withDSA";
-
-            algorithms["DSAWITHSHA512"] = "SHA-512withDSA";
-            algorithms["DSAWITHSHA-512"] = "SHA-512withDSA";
-            algorithms["SHA512/DSA"] = "SHA-512withDSA";
-            algorithms["SHA-512/DSA"] = "SHA-512withDSA";
-            algorithms["SHA512WITHDSA"] = "SHA-512withDSA";
-            algorithms["SHA-512WITHDSA"] = "SHA-512withDSA";
-            algorithms[NistObjectIdentifiers.DsaWithSha512.Id] = "SHA-512withDSA";
-
-            algorithms["NONEWITHECDSA"] = "NONEwithECDSA";
-            algorithms["ECDSAWITHNONE"] = "NONEwithECDSA";
-
-            algorithms["ECDSA"] = "SHA-1withECDSA";
-            algorithms["SHA1/ECDSA"] = "SHA-1withECDSA";
-            algorithms["SHA-1/ECDSA"] = "SHA-1withECDSA";
-            algorithms["ECDSAWITHSHA1"] = "SHA-1withECDSA";
-            algorithms["ECDSAWITHSHA-1"] = "SHA-1withECDSA";
-            algorithms["SHA1WITHECDSA"] = "SHA-1withECDSA";
-            algorithms["SHA-1WITHECDSA"] = "SHA-1withECDSA";
-            algorithms[X9ObjectIdentifiers.ECDsaWithSha1.Id] = "SHA-1withECDSA";
-            algorithms[TeleTrusTObjectIdentifiers.ECSignWithSha1.Id] = "SHA-1withECDSA";
-
-            algorithms["SHA224/ECDSA"] = "SHA-224withECDSA";
-            algorithms["SHA-224/ECDSA"] = "SHA-224withECDSA";
-            algorithms["ECDSAWITHSHA224"] = "SHA-224withECDSA";
-            algorithms["ECDSAWITHSHA-224"] = "SHA-224withECDSA";
-            algorithms["SHA224WITHECDSA"] = "SHA-224withECDSA";
-            algorithms["SHA-224WITHECDSA"] = "SHA-224withECDSA";
-            algorithms[X9ObjectIdentifiers.ECDsaWithSha224.Id] = "SHA-224withECDSA";
-
-            algorithms["SHA256/ECDSA"] = "SHA-256withECDSA";
-            algorithms["SHA-256/ECDSA"] = "SHA-256withECDSA";
-            algorithms["ECDSAWITHSHA256"] = "SHA-256withECDSA";
-            algorithms["ECDSAWITHSHA-256"] = "SHA-256withECDSA";
-            algorithms["SHA256WITHECDSA"] = "SHA-256withECDSA";
-            algorithms["SHA-256WITHECDSA"] = "SHA-256withECDSA";
-            algorithms[X9ObjectIdentifiers.ECDsaWithSha256.Id] = "SHA-256withECDSA";
-
-            algorithms["SHA384/ECDSA"] = "SHA-384withECDSA";
-            algorithms["SHA-384/ECDSA"] = "SHA-384withECDSA";
-            algorithms["ECDSAWITHSHA384"] = "SHA-384withECDSA";
-            algorithms["ECDSAWITHSHA-384"] = "SHA-384withECDSA";
-            algorithms["SHA384WITHECDSA"] = "SHA-384withECDSA";
-            algorithms["SHA-384WITHECDSA"] = "SHA-384withECDSA";
-            algorithms[X9ObjectIdentifiers.ECDsaWithSha384.Id] = "SHA-384withECDSA";
-
-            algorithms["SHA512/ECDSA"] = "SHA-512withECDSA";
-            algorithms["SHA-512/ECDSA"] = "SHA-512withECDSA";
-            algorithms["ECDSAWITHSHA512"] = "SHA-512withECDSA";
-            algorithms["ECDSAWITHSHA-512"] = "SHA-512withECDSA";
-            algorithms["SHA512WITHECDSA"] = "SHA-512withECDSA";
-            algorithms["SHA-512WITHECDSA"] = "SHA-512withECDSA";
-            algorithms[X9ObjectIdentifiers.ECDsaWithSha512.Id] = "SHA-512withECDSA";
-
-            algorithms["RIPEMD160/ECDSA"] = "RIPEMD160withECDSA";
-            algorithms["ECDSAWITHRIPEMD160"] = "RIPEMD160withECDSA";
-            algorithms["RIPEMD160WITHECDSA"] = "RIPEMD160withECDSA";
-            algorithms[TeleTrusTObjectIdentifiers.ECSignWithRipeMD160.Id] = "RIPEMD160withECDSA";
-
-            algorithms["NONEWITHCVC-ECDSA"] = "NONEwithCVC-ECDSA";
-            algorithms["CVC-ECDSAWITHNONE"] = "NONEwithCVC-ECDSA";
-
-            algorithms["SHA1/CVC-ECDSA"] = "SHA-1withCVC-ECDSA";
-            algorithms["SHA-1/CVC-ECDSA"] = "SHA-1withCVC-ECDSA";
-            algorithms["CVC-ECDSAWITHSHA1"] = "SHA-1withCVC-ECDSA";
-            algorithms["CVC-ECDSAWITHSHA-1"] = "SHA-1withCVC-ECDSA";
-            algorithms["SHA1WITHCVC-ECDSA"] = "SHA-1withCVC-ECDSA";
-            algorithms["SHA-1WITHCVC-ECDSA"] = "SHA-1withCVC-ECDSA";
-            algorithms[EacObjectIdentifiers.id_TA_ECDSA_SHA_1.Id] = "SHA-1withCVC-ECDSA";
-
-            algorithms["SHA224/CVC-ECDSA"] = "SHA-224withCVC-ECDSA";
-            algorithms["SHA-224/CVC-ECDSA"] = "SHA-224withCVC-ECDSA";
-            algorithms["CVC-ECDSAWITHSHA224"] = "SHA-224withCVC-ECDSA";
-            algorithms["CVC-ECDSAWITHSHA-224"] = "SHA-224withCVC-ECDSA";
-            algorithms["SHA224WITHCVC-ECDSA"] = "SHA-224withCVC-ECDSA";
-            algorithms["SHA-224WITHCVC-ECDSA"] = "SHA-224withCVC-ECDSA";
-            algorithms[EacObjectIdentifiers.id_TA_ECDSA_SHA_224.Id] = "SHA-224withCVC-ECDSA";
-
-            algorithms["SHA256/CVC-ECDSA"] = "SHA-256withCVC-ECDSA";
-            algorithms["SHA-256/CVC-ECDSA"] = "SHA-256withCVC-ECDSA";
-            algorithms["CVC-ECDSAWITHSHA256"] = "SHA-256withCVC-ECDSA";
-            algorithms["CVC-ECDSAWITHSHA-256"] = "SHA-256withCVC-ECDSA";
-            algorithms["SHA256WITHCVC-ECDSA"] = "SHA-256withCVC-ECDSA";
-            algorithms["SHA-256WITHCVC-ECDSA"] = "SHA-256withCVC-ECDSA";
-            algorithms[EacObjectIdentifiers.id_TA_ECDSA_SHA_256.Id] = "SHA-256withCVC-ECDSA";
-
-            algorithms["SHA384/CVC-ECDSA"] = "SHA-384withCVC-ECDSA";
-            algorithms["SHA-384/CVC-ECDSA"] = "SHA-384withCVC-ECDSA";
-            algorithms["CVC-ECDSAWITHSHA384"] = "SHA-384withCVC-ECDSA";
-            algorithms["CVC-ECDSAWITHSHA-384"] = "SHA-384withCVC-ECDSA";
-            algorithms["SHA384WITHCVC-ECDSA"] = "SHA-384withCVC-ECDSA";
-            algorithms["SHA-384WITHCVC-ECDSA"] = "SHA-384withCVC-ECDSA";
-            algorithms[EacObjectIdentifiers.id_TA_ECDSA_SHA_384.Id] = "SHA-384withCVC-ECDSA";
-
-            algorithms["SHA512/CVC-ECDSA"] = "SHA-512withCVC-ECDSA";
-            algorithms["SHA-512/CVC-ECDSA"] = "SHA-512withCVC-ECDSA";
-            algorithms["CVC-ECDSAWITHSHA512"] = "SHA-512withCVC-ECDSA";
-            algorithms["CVC-ECDSAWITHSHA-512"] = "SHA-512withCVC-ECDSA";
-            algorithms["SHA512WITHCVC-ECDSA"] = "SHA-512withCVC-ECDSA";
-            algorithms["SHA-512WITHCVC-ECDSA"] = "SHA-512withCVC-ECDSA";
-            algorithms[EacObjectIdentifiers.id_TA_ECDSA_SHA_512.Id] = "SHA-512withCVC-ECDSA";
-
-            algorithms["NONEWITHPLAIN-ECDSA"] = "NONEwithPLAIN-ECDSA";
-            algorithms["PLAIN-ECDSAWITHNONE"] = "NONEwithPLAIN-ECDSA";
-
-            algorithms["SHA1/PLAIN-ECDSA"] = "SHA-1withPLAIN-ECDSA";
-            algorithms["SHA-1/PLAIN-ECDSA"] = "SHA-1withPLAIN-ECDSA";
-            algorithms["PLAIN-ECDSAWITHSHA1"] = "SHA-1withPLAIN-ECDSA";
-            algorithms["PLAIN-ECDSAWITHSHA-1"] = "SHA-1withPLAIN-ECDSA";
-            algorithms["SHA1WITHPLAIN-ECDSA"] = "SHA-1withPLAIN-ECDSA";
-            algorithms["SHA-1WITHPLAIN-ECDSA"] = "SHA-1withPLAIN-ECDSA";
-            algorithms[BsiObjectIdentifiers.ecdsa_plain_SHA1.Id] = "SHA-1withPLAIN-ECDSA";
-
-            algorithms["SHA224/PLAIN-ECDSA"] = "SHA-224withPLAIN-ECDSA";
-            algorithms["SHA-224/PLAIN-ECDSA"] = "SHA-224withPLAIN-ECDSA";
-            algorithms["PLAIN-ECDSAWITHSHA224"] = "SHA-224withPLAIN-ECDSA";
-            algorithms["PLAIN-ECDSAWITHSHA-224"] = "SHA-224withPLAIN-ECDSA";
-            algorithms["SHA224WITHPLAIN-ECDSA"] = "SHA-224withPLAIN-ECDSA";
-            algorithms["SHA-224WITHPLAIN-ECDSA"] = "SHA-224withPLAIN-ECDSA";
-            algorithms[BsiObjectIdentifiers.ecdsa_plain_SHA224.Id] = "SHA-224withPLAIN-ECDSA";
-
-            algorithms["SHA256/PLAIN-ECDSA"] = "SHA-256withPLAIN-ECDSA";
-            algorithms["SHA-256/PLAIN-ECDSA"] = "SHA-256withPLAIN-ECDSA";
-            algorithms["PLAIN-ECDSAWITHSHA256"] = "SHA-256withPLAIN-ECDSA";
-            algorithms["PLAIN-ECDSAWITHSHA-256"] = "SHA-256withPLAIN-ECDSA";
-            algorithms["SHA256WITHPLAIN-ECDSA"] = "SHA-256withPLAIN-ECDSA";
-            algorithms["SHA-256WITHPLAIN-ECDSA"] = "SHA-256withPLAIN-ECDSA";
-            algorithms[BsiObjectIdentifiers.ecdsa_plain_SHA256.Id] = "SHA-256withPLAIN-ECDSA";
-
-            algorithms["SHA384/PLAIN-ECDSA"] = "SHA-384withPLAIN-ECDSA";
-            algorithms["SHA-384/PLAIN-ECDSA"] = "SHA-384withPLAIN-ECDSA";
-            algorithms["PLAIN-ECDSAWITHSHA384"] = "SHA-384withPLAIN-ECDSA";
-            algorithms["PLAIN-ECDSAWITHSHA-384"] = "SHA-384withPLAIN-ECDSA";
-            algorithms["SHA384WITHPLAIN-ECDSA"] = "SHA-384withPLAIN-ECDSA";
-            algorithms["SHA-384WITHPLAIN-ECDSA"] = "SHA-384withPLAIN-ECDSA";
-            algorithms[BsiObjectIdentifiers.ecdsa_plain_SHA384.Id] = "SHA-384withPLAIN-ECDSA";
-
-            algorithms["SHA512/PLAIN-ECDSA"] = "SHA-512withPLAIN-ECDSA";
-            algorithms["SHA-512/PLAIN-ECDSA"] = "SHA-512withPLAIN-ECDSA";
-            algorithms["PLAIN-ECDSAWITHSHA512"] = "SHA-512withPLAIN-ECDSA";
-            algorithms["PLAIN-ECDSAWITHSHA-512"] = "SHA-512withPLAIN-ECDSA";
-            algorithms["SHA512WITHPLAIN-ECDSA"] = "SHA-512withPLAIN-ECDSA";
-            algorithms["SHA-512WITHPLAIN-ECDSA"] = "SHA-512withPLAIN-ECDSA";
-            algorithms[BsiObjectIdentifiers.ecdsa_plain_SHA512.Id] = "SHA-512withPLAIN-ECDSA";
-
-            algorithms["RIPEMD160/PLAIN-ECDSA"] = "RIPEMD160withPLAIN-ECDSA";
-            algorithms["PLAIN-ECDSAWITHRIPEMD160"] = "RIPEMD160withPLAIN-ECDSA";
-            algorithms["RIPEMD160WITHPLAIN-ECDSA"] = "RIPEMD160withPLAIN-ECDSA";
-            algorithms[BsiObjectIdentifiers.ecdsa_plain_RIPEMD160.Id] = "RIPEMD160withPLAIN-ECDSA";
-
-            algorithms["SHA1WITHECNR"] = "SHA-1withECNR";
-            algorithms["SHA-1WITHECNR"] = "SHA-1withECNR";
-            algorithms["SHA224WITHECNR"] = "SHA-224withECNR";
-            algorithms["SHA-224WITHECNR"] = "SHA-224withECNR";
-            algorithms["SHA256WITHECNR"] = "SHA-256withECNR";
-            algorithms["SHA-256WITHECNR"] = "SHA-256withECNR";
-            algorithms["SHA384WITHECNR"] = "SHA-384withECNR";
-            algorithms["SHA-384WITHECNR"] = "SHA-384withECNR";
-            algorithms["SHA512WITHECNR"] = "SHA-512withECNR";
-            algorithms["SHA-512WITHECNR"] = "SHA-512withECNR";
-
-            algorithms["GOST-3410"] = "GOST3410";
-            algorithms["GOST-3410-94"] = "GOST3410";
-            algorithms["GOST3411WITHGOST3410"] = "GOST3410";
-            algorithms[CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94.Id] = "GOST3410";
-
-            algorithms["ECGOST-3410"] = "ECGOST3410";
-            algorithms["ECGOST-3410-2001"] = "ECGOST3410";
-            algorithms["GOST3411WITHECGOST3410"] = "ECGOST3410";
-            algorithms[CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001.Id] = "ECGOST3410";
-
-            algorithms["ED25519"] = "Ed25519";
-            algorithms[EdECObjectIdentifiers.id_Ed25519.Id] = "Ed25519";
-            algorithms["ED25519CTX"] = "Ed25519ctx";
-            algorithms["ED25519PH"] = "Ed25519ph";
-            algorithms["ED448"] = "Ed448";
-            algorithms[EdECObjectIdentifiers.id_Ed448.Id] = "Ed448";
-            algorithms["ED448PH"] = "Ed448ph";
-
-            algorithms["SHA256WITHSM2"] = "SHA256withSM2";
-            algorithms[GMObjectIdentifiers.sm2sign_with_sha256.Id] = "SHA256withSM2";
-            algorithms["SM3WITHSM2"] = "SM3withSM2";
-            algorithms[GMObjectIdentifiers.sm2sign_with_sm3.Id] = "SM3withSM2";
-
-            oids["MD2withRSA"] = PkcsObjectIdentifiers.MD2WithRsaEncryption;
-            oids["MD4withRSA"] = PkcsObjectIdentifiers.MD4WithRsaEncryption;
-            oids["MD5withRSA"] = PkcsObjectIdentifiers.MD5WithRsaEncryption;
-
-            oids["SHA-1withRSA"] = PkcsObjectIdentifiers.Sha1WithRsaEncryption;
-            oids["SHA-224withRSA"] = PkcsObjectIdentifiers.Sha224WithRsaEncryption;
-            oids["SHA-256withRSA"] = PkcsObjectIdentifiers.Sha256WithRsaEncryption;
-            oids["SHA-384withRSA"] = PkcsObjectIdentifiers.Sha384WithRsaEncryption;
-            oids["SHA-512withRSA"] = PkcsObjectIdentifiers.Sha512WithRsaEncryption;
-            oids["SHA-512(224)withRSA"] = PkcsObjectIdentifiers.Sha512_224WithRSAEncryption;
-            oids["SHA-512(256)withRSA"] = PkcsObjectIdentifiers.Sha512_256WithRSAEncryption;
-            oids["SHA3-224withRSA"] = NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_224;
-            oids["SHA3-256withRSA"] = NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_256;
-            oids["SHA3-384withRSA"] = NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_384;
-            oids["SHA3-512withRSA"] = NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_512;
-
-            oids["PSSwithRSA"] = PkcsObjectIdentifiers.IdRsassaPss;
-            oids["SHA-1withRSAandMGF1"] = PkcsObjectIdentifiers.IdRsassaPss;
-            oids["SHA-224withRSAandMGF1"] = PkcsObjectIdentifiers.IdRsassaPss;
-            oids["SHA-256withRSAandMGF1"] = PkcsObjectIdentifiers.IdRsassaPss;
-            oids["SHA-384withRSAandMGF1"] = PkcsObjectIdentifiers.IdRsassaPss;
-            oids["SHA-512withRSAandMGF1"] = PkcsObjectIdentifiers.IdRsassaPss;
-
-            oids["RIPEMD128withRSA"] = TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128;
-            oids["RIPEMD160withRSA"] = TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160;
-            oids["RIPEMD256withRSA"] = TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256;
-
-            oids["SHA-1withDSA"] = X9ObjectIdentifiers.IdDsaWithSha1;
-
-            oids["SHA-1withECDSA"] = X9ObjectIdentifiers.ECDsaWithSha1;
-            oids["SHA-224withECDSA"] = X9ObjectIdentifiers.ECDsaWithSha224;
-            oids["SHA-256withECDSA"] = X9ObjectIdentifiers.ECDsaWithSha256;
-            oids["SHA-384withECDSA"] = X9ObjectIdentifiers.ECDsaWithSha384;
-            oids["SHA-512withECDSA"] = X9ObjectIdentifiers.ECDsaWithSha512;
-            oids["RIPEMD160withECDSA"] = TeleTrusTObjectIdentifiers.ECSignWithRipeMD160;
-
-            oids["SHA-1withCVC-ECDSA"] = EacObjectIdentifiers.id_TA_ECDSA_SHA_1;
-            oids["SHA-224withCVC-ECDSA"] = EacObjectIdentifiers.id_TA_ECDSA_SHA_224;
-            oids["SHA-256withCVC-ECDSA"] = EacObjectIdentifiers.id_TA_ECDSA_SHA_256;
-            oids["SHA-384withCVC-ECDSA"] = EacObjectIdentifiers.id_TA_ECDSA_SHA_384;
-            oids["SHA-512withCVC-ECDSA"] = EacObjectIdentifiers.id_TA_ECDSA_SHA_512;
-
-            oids["SHA-1withPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_SHA1;
-            oids["SHA-224withPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_SHA224;
-            oids["SHA-256withPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_SHA256;
-            oids["SHA-384withPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_SHA384;
-            oids["SHA-512withPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_SHA512;
-            oids["RIPEMD160withPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_RIPEMD160;
-
-            oids["GOST3410"] = CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94;
-            oids["ECGOST3410"] = CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001;
-
-            oids["Ed25519"] = EdECObjectIdentifiers.id_Ed25519;
-            oids["Ed448"] = EdECObjectIdentifiers.id_Ed448;
-
-            oids["SHA256withSM2"] = GMObjectIdentifiers.sm2sign_with_sha256;
-            oids["SM3withSM2"] = GMObjectIdentifiers.sm2sign_with_sm3;
+            AlgorithmMap["MD2WITHRSA"] = "MD2withRSA";
+            AlgorithmMap["MD2WITHRSAENCRYPTION"] = "MD2withRSA";
+            AlgorithmMap[PkcsObjectIdentifiers.MD2WithRsaEncryption.Id] = "MD2withRSA";
+
+            AlgorithmMap["MD4WITHRSA"] = "MD4withRSA";
+            AlgorithmMap["MD4WITHRSAENCRYPTION"] = "MD4withRSA";
+            AlgorithmMap[PkcsObjectIdentifiers.MD4WithRsaEncryption.Id] = "MD4withRSA";
+            AlgorithmMap[OiwObjectIdentifiers.MD4WithRsa.Id] = "MD4withRSA";
+			AlgorithmMap[OiwObjectIdentifiers.MD4WithRsaEncryption.Id] = "MD4withRSA";
+
+			AlgorithmMap["MD5WITHRSA"] = "MD5withRSA";
+            AlgorithmMap["MD5WITHRSAENCRYPTION"] = "MD5withRSA";
+            AlgorithmMap[PkcsObjectIdentifiers.MD5WithRsaEncryption.Id] = "MD5withRSA";
+            AlgorithmMap[OiwObjectIdentifiers.MD5WithRsa.Id] = "MD5withRSA";
+
+            AlgorithmMap["SHA1WITHRSA"] = "SHA-1withRSA";
+            AlgorithmMap["SHA-1WITHRSA"] = "SHA-1withRSA";
+            AlgorithmMap["SHA1WITHRSAENCRYPTION"] = "SHA-1withRSA";
+            AlgorithmMap["SHA-1WITHRSAENCRYPTION"] = "SHA-1withRSA";
+            AlgorithmMap[PkcsObjectIdentifiers.Sha1WithRsaEncryption.Id] = "SHA-1withRSA";
+            AlgorithmMap[OiwObjectIdentifiers.Sha1WithRsa.Id] = "SHA-1withRSA";
+
+            AlgorithmMap["SHA224WITHRSA"] = "SHA-224withRSA";
+            AlgorithmMap["SHA-224WITHRSA"] = "SHA-224withRSA";
+            AlgorithmMap["SHA224WITHRSAENCRYPTION"] = "SHA-224withRSA";
+            AlgorithmMap["SHA-224WITHRSAENCRYPTION"] = "SHA-224withRSA";
+            AlgorithmMap[PkcsObjectIdentifiers.Sha224WithRsaEncryption.Id] = "SHA-224withRSA";
+
+            AlgorithmMap["SHA256WITHRSA"] = "SHA-256withRSA";
+            AlgorithmMap["SHA-256WITHRSA"] = "SHA-256withRSA";
+            AlgorithmMap["SHA256WITHRSAENCRYPTION"] = "SHA-256withRSA";
+            AlgorithmMap["SHA-256WITHRSAENCRYPTION"] = "SHA-256withRSA";
+            AlgorithmMap[PkcsObjectIdentifiers.Sha256WithRsaEncryption.Id] = "SHA-256withRSA";
+
+            AlgorithmMap["SHA384WITHRSA"] = "SHA-384withRSA";
+            AlgorithmMap["SHA-384WITHRSA"] = "SHA-384withRSA";
+            AlgorithmMap["SHA384WITHRSAENCRYPTION"] = "SHA-384withRSA";
+            AlgorithmMap["SHA-384WITHRSAENCRYPTION"] = "SHA-384withRSA";
+            AlgorithmMap[PkcsObjectIdentifiers.Sha384WithRsaEncryption.Id] = "SHA-384withRSA";
+
+            AlgorithmMap["SHA512WITHRSA"] = "SHA-512withRSA";
+            AlgorithmMap["SHA-512WITHRSA"] = "SHA-512withRSA";
+            AlgorithmMap["SHA512WITHRSAENCRYPTION"] = "SHA-512withRSA";
+            AlgorithmMap["SHA-512WITHRSAENCRYPTION"] = "SHA-512withRSA";
+            AlgorithmMap[PkcsObjectIdentifiers.Sha512WithRsaEncryption.Id] = "SHA-512withRSA";
+
+            AlgorithmMap["SHA512(224)WITHRSA"] = "SHA-512(224)withRSA";
+            AlgorithmMap["SHA-512(224)WITHRSA"] = "SHA-512(224)withRSA";
+            AlgorithmMap["SHA512(224)WITHRSAENCRYPTION"] = "SHA-512(224)withRSA";
+            AlgorithmMap["SHA-512(224)WITHRSAENCRYPTION"] = "SHA-512(224)withRSA";
+            AlgorithmMap[PkcsObjectIdentifiers.Sha512_224WithRSAEncryption.Id] = "SHA-512(224)withRSA";
+
+            AlgorithmMap["SHA512(256)WITHRSA"] = "SHA-512(256)withRSA";
+            AlgorithmMap["SHA-512(256)WITHRSA"] = "SHA-512(256)withRSA";
+            AlgorithmMap["SHA512(256)WITHRSAENCRYPTION"] = "SHA-512(256)withRSA";
+            AlgorithmMap["SHA-512(256)WITHRSAENCRYPTION"] = "SHA-512(256)withRSA";
+            AlgorithmMap[PkcsObjectIdentifiers.Sha512_256WithRSAEncryption.Id] = "SHA-512(256)withRSA";
+
+            AlgorithmMap["SHA3-224WITHRSA"] = "SHA3-224withRSA";
+            AlgorithmMap["SHA3-224WITHRSAENCRYPTION"] = "SHA3-224withRSA";
+            AlgorithmMap[NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_224.Id] = "SHA3-224withRSA";
+            AlgorithmMap["SHA3-256WITHRSA"] = "SHA3-256withRSA";
+            AlgorithmMap["SHA3-256WITHRSAENCRYPTION"] = "SHA3-256withRSA";
+            AlgorithmMap[NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_256.Id] = "SHA3-256withRSA";
+            AlgorithmMap["SHA3-384WITHRSA"] = "SHA3-384withRSA";
+            AlgorithmMap["SHA3-384WITHRSAENCRYPTION"] = "SHA3-384withRSA";
+            AlgorithmMap[NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_384.Id] = "SHA3-384withRSA";
+            AlgorithmMap["SHA3-512WITHRSA"] = "SHA3-512withRSA";
+            AlgorithmMap["SHA3-512WITHRSAENCRYPTION"] = "SHA3-512withRSA";
+            AlgorithmMap[NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_512.Id] = "SHA3-512withRSA";
+
+            AlgorithmMap["PSSWITHRSA"] = "PSSwithRSA";
+            AlgorithmMap["RSASSA-PSS"] = "PSSwithRSA";
+            AlgorithmMap[PkcsObjectIdentifiers.IdRsassaPss.Id] = "PSSwithRSA";
+            AlgorithmMap["RSAPSS"] = "PSSwithRSA";
+
+            AlgorithmMap["SHA1WITHRSAANDMGF1"] = "SHA-1withRSAandMGF1";
+            AlgorithmMap["SHA-1WITHRSAANDMGF1"] = "SHA-1withRSAandMGF1";
+            AlgorithmMap["SHA1WITHRSA/PSS"] = "SHA-1withRSAandMGF1";
+            AlgorithmMap["SHA-1WITHRSA/PSS"] = "SHA-1withRSAandMGF1";
+            AlgorithmMap["SHA1WITHRSASSA-PSS"] = "SHA-1withRSAandMGF1";
+            AlgorithmMap["SHA-1WITHRSASSA-PSS"] = "SHA-1withRSAandMGF1";
+
+            AlgorithmMap["SHA224WITHRSAANDMGF1"] = "SHA-224withRSAandMGF1";
+            AlgorithmMap["SHA-224WITHRSAANDMGF1"] = "SHA-224withRSAandMGF1";
+            AlgorithmMap["SHA224WITHRSA/PSS"] = "SHA-224withRSAandMGF1";
+            AlgorithmMap["SHA-224WITHRSA/PSS"] = "SHA-224withRSAandMGF1";
+            AlgorithmMap["SHA224WITHRSASSA-PSS"] = "SHA-224withRSAandMGF1";
+            AlgorithmMap["SHA-224WITHRSASSA-PSS"] = "SHA-224withRSAandMGF1";
+
+            AlgorithmMap["SHA256WITHRSAANDMGF1"] = "SHA-256withRSAandMGF1";
+            AlgorithmMap["SHA-256WITHRSAANDMGF1"] = "SHA-256withRSAandMGF1";
+            AlgorithmMap["SHA256WITHRSA/PSS"] = "SHA-256withRSAandMGF1";
+            AlgorithmMap["SHA-256WITHRSA/PSS"] = "SHA-256withRSAandMGF1";
+            AlgorithmMap["SHA256WITHRSASSA-PSS"] = "SHA-256withRSAandMGF1";
+            AlgorithmMap["SHA-256WITHRSASSA-PSS"] = "SHA-256withRSAandMGF1";
+
+            AlgorithmMap["SHA384WITHRSAANDMGF1"] = "SHA-384withRSAandMGF1";
+            AlgorithmMap["SHA-384WITHRSAANDMGF1"] = "SHA-384withRSAandMGF1";
+            AlgorithmMap["SHA384WITHRSA/PSS"] = "SHA-384withRSAandMGF1";
+            AlgorithmMap["SHA-384WITHRSA/PSS"] = "SHA-384withRSAandMGF1";
+            AlgorithmMap["SHA384WITHRSASSA-PSS"] = "SHA-384withRSAandMGF1";
+            AlgorithmMap["SHA-384WITHRSASSA-PSS"] = "SHA-384withRSAandMGF1";
+
+            AlgorithmMap["SHA512WITHRSAANDMGF1"] = "SHA-512withRSAandMGF1";
+            AlgorithmMap["SHA-512WITHRSAANDMGF1"] = "SHA-512withRSAandMGF1";
+            AlgorithmMap["SHA512WITHRSA/PSS"] = "SHA-512withRSAandMGF1";
+            AlgorithmMap["SHA-512WITHRSA/PSS"] = "SHA-512withRSAandMGF1";
+            AlgorithmMap["SHA512WITHRSASSA-PSS"] = "SHA-512withRSAandMGF1";
+            AlgorithmMap["SHA-512WITHRSASSA-PSS"] = "SHA-512withRSAandMGF1";
+
+            AlgorithmMap["RIPEMD128WITHRSA"] = "RIPEMD128withRSA";
+            AlgorithmMap["RIPEMD128WITHRSAENCRYPTION"] = "RIPEMD128withRSA";
+            AlgorithmMap[TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128.Id] = "RIPEMD128withRSA";
+
+            AlgorithmMap["RIPEMD160WITHRSA"] = "RIPEMD160withRSA";
+            AlgorithmMap["RIPEMD160WITHRSAENCRYPTION"] = "RIPEMD160withRSA";
+            AlgorithmMap[TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160.Id] = "RIPEMD160withRSA";
+
+            AlgorithmMap["RIPEMD256WITHRSA"] = "RIPEMD256withRSA";
+            AlgorithmMap["RIPEMD256WITHRSAENCRYPTION"] = "RIPEMD256withRSA";
+            AlgorithmMap[TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256.Id] = "RIPEMD256withRSA";
+
+            AlgorithmMap["NONEWITHRSA"] = "RSA";
+            AlgorithmMap["RSAWITHNONE"] = "RSA";
+            AlgorithmMap["RAWRSA"] = "RSA";
+
+            AlgorithmMap["RAWRSAPSS"] = "RAWRSASSA-PSS";
+            AlgorithmMap["NONEWITHRSAPSS"] = "RAWRSASSA-PSS";
+            AlgorithmMap["NONEWITHRSASSA-PSS"] = "RAWRSASSA-PSS";
+
+            AlgorithmMap["NONEWITHDSA"] = "NONEwithDSA";
+            AlgorithmMap["DSAWITHNONE"] = "NONEwithDSA";
+            AlgorithmMap["RAWDSA"] = "NONEwithDSA";
+
+            AlgorithmMap["DSA"] = "SHA-1withDSA";
+            AlgorithmMap["DSAWITHSHA1"] = "SHA-1withDSA";
+            AlgorithmMap["DSAWITHSHA-1"] = "SHA-1withDSA";
+            AlgorithmMap["SHA/DSA"] = "SHA-1withDSA";
+            AlgorithmMap["SHA1/DSA"] = "SHA-1withDSA";
+            AlgorithmMap["SHA-1/DSA"] = "SHA-1withDSA";
+            AlgorithmMap["SHA1WITHDSA"] = "SHA-1withDSA";
+            AlgorithmMap["SHA-1WITHDSA"] = "SHA-1withDSA";
+            AlgorithmMap[X9ObjectIdentifiers.IdDsaWithSha1.Id] = "SHA-1withDSA";
+            AlgorithmMap[OiwObjectIdentifiers.DsaWithSha1.Id] = "SHA-1withDSA";
+
+            AlgorithmMap["DSAWITHSHA224"] = "SHA-224withDSA";
+            AlgorithmMap["DSAWITHSHA-224"] = "SHA-224withDSA";
+            AlgorithmMap["SHA224/DSA"] = "SHA-224withDSA";
+            AlgorithmMap["SHA-224/DSA"] = "SHA-224withDSA";
+            AlgorithmMap["SHA224WITHDSA"] = "SHA-224withDSA";
+            AlgorithmMap["SHA-224WITHDSA"] = "SHA-224withDSA";
+            AlgorithmMap[NistObjectIdentifiers.DsaWithSha224.Id] = "SHA-224withDSA";
+
+            AlgorithmMap["DSAWITHSHA256"] = "SHA-256withDSA";
+            AlgorithmMap["DSAWITHSHA-256"] = "SHA-256withDSA";
+            AlgorithmMap["SHA256/DSA"] = "SHA-256withDSA";
+            AlgorithmMap["SHA-256/DSA"] = "SHA-256withDSA";
+            AlgorithmMap["SHA256WITHDSA"] = "SHA-256withDSA";
+            AlgorithmMap["SHA-256WITHDSA"] = "SHA-256withDSA";
+            AlgorithmMap[NistObjectIdentifiers.DsaWithSha256.Id] = "SHA-256withDSA";
+
+            AlgorithmMap["DSAWITHSHA384"] = "SHA-384withDSA";
+            AlgorithmMap["DSAWITHSHA-384"] = "SHA-384withDSA";
+            AlgorithmMap["SHA384/DSA"] = "SHA-384withDSA";
+            AlgorithmMap["SHA-384/DSA"] = "SHA-384withDSA";
+            AlgorithmMap["SHA384WITHDSA"] = "SHA-384withDSA";
+            AlgorithmMap["SHA-384WITHDSA"] = "SHA-384withDSA";
+            AlgorithmMap[NistObjectIdentifiers.DsaWithSha384.Id] = "SHA-384withDSA";
+
+            AlgorithmMap["DSAWITHSHA512"] = "SHA-512withDSA";
+            AlgorithmMap["DSAWITHSHA-512"] = "SHA-512withDSA";
+            AlgorithmMap["SHA512/DSA"] = "SHA-512withDSA";
+            AlgorithmMap["SHA-512/DSA"] = "SHA-512withDSA";
+            AlgorithmMap["SHA512WITHDSA"] = "SHA-512withDSA";
+            AlgorithmMap["SHA-512WITHDSA"] = "SHA-512withDSA";
+            AlgorithmMap[NistObjectIdentifiers.DsaWithSha512.Id] = "SHA-512withDSA";
+
+            AlgorithmMap["NONEWITHECDSA"] = "NONEwithECDSA";
+            AlgorithmMap["ECDSAWITHNONE"] = "NONEwithECDSA";
+
+            AlgorithmMap["ECDSA"] = "SHA-1withECDSA";
+            AlgorithmMap["SHA1/ECDSA"] = "SHA-1withECDSA";
+            AlgorithmMap["SHA-1/ECDSA"] = "SHA-1withECDSA";
+            AlgorithmMap["ECDSAWITHSHA1"] = "SHA-1withECDSA";
+            AlgorithmMap["ECDSAWITHSHA-1"] = "SHA-1withECDSA";
+            AlgorithmMap["SHA1WITHECDSA"] = "SHA-1withECDSA";
+            AlgorithmMap["SHA-1WITHECDSA"] = "SHA-1withECDSA";
+            AlgorithmMap[X9ObjectIdentifiers.ECDsaWithSha1.Id] = "SHA-1withECDSA";
+            AlgorithmMap[TeleTrusTObjectIdentifiers.ECSignWithSha1.Id] = "SHA-1withECDSA";
+
+            AlgorithmMap["SHA224/ECDSA"] = "SHA-224withECDSA";
+            AlgorithmMap["SHA-224/ECDSA"] = "SHA-224withECDSA";
+            AlgorithmMap["ECDSAWITHSHA224"] = "SHA-224withECDSA";
+            AlgorithmMap["ECDSAWITHSHA-224"] = "SHA-224withECDSA";
+            AlgorithmMap["SHA224WITHECDSA"] = "SHA-224withECDSA";
+            AlgorithmMap["SHA-224WITHECDSA"] = "SHA-224withECDSA";
+            AlgorithmMap[X9ObjectIdentifiers.ECDsaWithSha224.Id] = "SHA-224withECDSA";
+
+            AlgorithmMap["SHA256/ECDSA"] = "SHA-256withECDSA";
+            AlgorithmMap["SHA-256/ECDSA"] = "SHA-256withECDSA";
+            AlgorithmMap["ECDSAWITHSHA256"] = "SHA-256withECDSA";
+            AlgorithmMap["ECDSAWITHSHA-256"] = "SHA-256withECDSA";
+            AlgorithmMap["SHA256WITHECDSA"] = "SHA-256withECDSA";
+            AlgorithmMap["SHA-256WITHECDSA"] = "SHA-256withECDSA";
+            AlgorithmMap[X9ObjectIdentifiers.ECDsaWithSha256.Id] = "SHA-256withECDSA";
+
+            AlgorithmMap["SHA384/ECDSA"] = "SHA-384withECDSA";
+            AlgorithmMap["SHA-384/ECDSA"] = "SHA-384withECDSA";
+            AlgorithmMap["ECDSAWITHSHA384"] = "SHA-384withECDSA";
+            AlgorithmMap["ECDSAWITHSHA-384"] = "SHA-384withECDSA";
+            AlgorithmMap["SHA384WITHECDSA"] = "SHA-384withECDSA";
+            AlgorithmMap["SHA-384WITHECDSA"] = "SHA-384withECDSA";
+            AlgorithmMap[X9ObjectIdentifiers.ECDsaWithSha384.Id] = "SHA-384withECDSA";
+
+            AlgorithmMap["SHA512/ECDSA"] = "SHA-512withECDSA";
+            AlgorithmMap["SHA-512/ECDSA"] = "SHA-512withECDSA";
+            AlgorithmMap["ECDSAWITHSHA512"] = "SHA-512withECDSA";
+            AlgorithmMap["ECDSAWITHSHA-512"] = "SHA-512withECDSA";
+            AlgorithmMap["SHA512WITHECDSA"] = "SHA-512withECDSA";
+            AlgorithmMap["SHA-512WITHECDSA"] = "SHA-512withECDSA";
+            AlgorithmMap[X9ObjectIdentifiers.ECDsaWithSha512.Id] = "SHA-512withECDSA";
+
+            AlgorithmMap["RIPEMD160/ECDSA"] = "RIPEMD160withECDSA";
+            AlgorithmMap["ECDSAWITHRIPEMD160"] = "RIPEMD160withECDSA";
+            AlgorithmMap["RIPEMD160WITHECDSA"] = "RIPEMD160withECDSA";
+            AlgorithmMap[TeleTrusTObjectIdentifiers.ECSignWithRipeMD160.Id] = "RIPEMD160withECDSA";
+
+            AlgorithmMap["NONEWITHCVC-ECDSA"] = "NONEwithCVC-ECDSA";
+            AlgorithmMap["CVC-ECDSAWITHNONE"] = "NONEwithCVC-ECDSA";
+
+            AlgorithmMap["SHA1/CVC-ECDSA"] = "SHA-1withCVC-ECDSA";
+            AlgorithmMap["SHA-1/CVC-ECDSA"] = "SHA-1withCVC-ECDSA";
+            AlgorithmMap["CVC-ECDSAWITHSHA1"] = "SHA-1withCVC-ECDSA";
+            AlgorithmMap["CVC-ECDSAWITHSHA-1"] = "SHA-1withCVC-ECDSA";
+            AlgorithmMap["SHA1WITHCVC-ECDSA"] = "SHA-1withCVC-ECDSA";
+            AlgorithmMap["SHA-1WITHCVC-ECDSA"] = "SHA-1withCVC-ECDSA";
+            AlgorithmMap[EacObjectIdentifiers.id_TA_ECDSA_SHA_1.Id] = "SHA-1withCVC-ECDSA";
+
+            AlgorithmMap["SHA224/CVC-ECDSA"] = "SHA-224withCVC-ECDSA";
+            AlgorithmMap["SHA-224/CVC-ECDSA"] = "SHA-224withCVC-ECDSA";
+            AlgorithmMap["CVC-ECDSAWITHSHA224"] = "SHA-224withCVC-ECDSA";
+            AlgorithmMap["CVC-ECDSAWITHSHA-224"] = "SHA-224withCVC-ECDSA";
+            AlgorithmMap["SHA224WITHCVC-ECDSA"] = "SHA-224withCVC-ECDSA";
+            AlgorithmMap["SHA-224WITHCVC-ECDSA"] = "SHA-224withCVC-ECDSA";
+            AlgorithmMap[EacObjectIdentifiers.id_TA_ECDSA_SHA_224.Id] = "SHA-224withCVC-ECDSA";
+
+            AlgorithmMap["SHA256/CVC-ECDSA"] = "SHA-256withCVC-ECDSA";
+            AlgorithmMap["SHA-256/CVC-ECDSA"] = "SHA-256withCVC-ECDSA";
+            AlgorithmMap["CVC-ECDSAWITHSHA256"] = "SHA-256withCVC-ECDSA";
+            AlgorithmMap["CVC-ECDSAWITHSHA-256"] = "SHA-256withCVC-ECDSA";
+            AlgorithmMap["SHA256WITHCVC-ECDSA"] = "SHA-256withCVC-ECDSA";
+            AlgorithmMap["SHA-256WITHCVC-ECDSA"] = "SHA-256withCVC-ECDSA";
+            AlgorithmMap[EacObjectIdentifiers.id_TA_ECDSA_SHA_256.Id] = "SHA-256withCVC-ECDSA";
+
+            AlgorithmMap["SHA384/CVC-ECDSA"] = "SHA-384withCVC-ECDSA";
+            AlgorithmMap["SHA-384/CVC-ECDSA"] = "SHA-384withCVC-ECDSA";
+            AlgorithmMap["CVC-ECDSAWITHSHA384"] = "SHA-384withCVC-ECDSA";
+            AlgorithmMap["CVC-ECDSAWITHSHA-384"] = "SHA-384withCVC-ECDSA";
+            AlgorithmMap["SHA384WITHCVC-ECDSA"] = "SHA-384withCVC-ECDSA";
+            AlgorithmMap["SHA-384WITHCVC-ECDSA"] = "SHA-384withCVC-ECDSA";
+            AlgorithmMap[EacObjectIdentifiers.id_TA_ECDSA_SHA_384.Id] = "SHA-384withCVC-ECDSA";
+
+            AlgorithmMap["SHA512/CVC-ECDSA"] = "SHA-512withCVC-ECDSA";
+            AlgorithmMap["SHA-512/CVC-ECDSA"] = "SHA-512withCVC-ECDSA";
+            AlgorithmMap["CVC-ECDSAWITHSHA512"] = "SHA-512withCVC-ECDSA";
+            AlgorithmMap["CVC-ECDSAWITHSHA-512"] = "SHA-512withCVC-ECDSA";
+            AlgorithmMap["SHA512WITHCVC-ECDSA"] = "SHA-512withCVC-ECDSA";
+            AlgorithmMap["SHA-512WITHCVC-ECDSA"] = "SHA-512withCVC-ECDSA";
+            AlgorithmMap[EacObjectIdentifiers.id_TA_ECDSA_SHA_512.Id] = "SHA-512withCVC-ECDSA";
+
+            AlgorithmMap["NONEWITHPLAIN-ECDSA"] = "NONEwithPLAIN-ECDSA";
+            AlgorithmMap["PLAIN-ECDSAWITHNONE"] = "NONEwithPLAIN-ECDSA";
+
+            AlgorithmMap["SHA1/PLAIN-ECDSA"] = "SHA-1withPLAIN-ECDSA";
+            AlgorithmMap["SHA-1/PLAIN-ECDSA"] = "SHA-1withPLAIN-ECDSA";
+            AlgorithmMap["PLAIN-ECDSAWITHSHA1"] = "SHA-1withPLAIN-ECDSA";
+            AlgorithmMap["PLAIN-ECDSAWITHSHA-1"] = "SHA-1withPLAIN-ECDSA";
+            AlgorithmMap["SHA1WITHPLAIN-ECDSA"] = "SHA-1withPLAIN-ECDSA";
+            AlgorithmMap["SHA-1WITHPLAIN-ECDSA"] = "SHA-1withPLAIN-ECDSA";
+            AlgorithmMap[BsiObjectIdentifiers.ecdsa_plain_SHA1.Id] = "SHA-1withPLAIN-ECDSA";
+
+            AlgorithmMap["SHA224/PLAIN-ECDSA"] = "SHA-224withPLAIN-ECDSA";
+            AlgorithmMap["SHA-224/PLAIN-ECDSA"] = "SHA-224withPLAIN-ECDSA";
+            AlgorithmMap["PLAIN-ECDSAWITHSHA224"] = "SHA-224withPLAIN-ECDSA";
+            AlgorithmMap["PLAIN-ECDSAWITHSHA-224"] = "SHA-224withPLAIN-ECDSA";
+            AlgorithmMap["SHA224WITHPLAIN-ECDSA"] = "SHA-224withPLAIN-ECDSA";
+            AlgorithmMap["SHA-224WITHPLAIN-ECDSA"] = "SHA-224withPLAIN-ECDSA";
+            AlgorithmMap[BsiObjectIdentifiers.ecdsa_plain_SHA224.Id] = "SHA-224withPLAIN-ECDSA";
+
+            AlgorithmMap["SHA256/PLAIN-ECDSA"] = "SHA-256withPLAIN-ECDSA";
+            AlgorithmMap["SHA-256/PLAIN-ECDSA"] = "SHA-256withPLAIN-ECDSA";
+            AlgorithmMap["PLAIN-ECDSAWITHSHA256"] = "SHA-256withPLAIN-ECDSA";
+            AlgorithmMap["PLAIN-ECDSAWITHSHA-256"] = "SHA-256withPLAIN-ECDSA";
+            AlgorithmMap["SHA256WITHPLAIN-ECDSA"] = "SHA-256withPLAIN-ECDSA";
+            AlgorithmMap["SHA-256WITHPLAIN-ECDSA"] = "SHA-256withPLAIN-ECDSA";
+            AlgorithmMap[BsiObjectIdentifiers.ecdsa_plain_SHA256.Id] = "SHA-256withPLAIN-ECDSA";
+
+            AlgorithmMap["SHA384/PLAIN-ECDSA"] = "SHA-384withPLAIN-ECDSA";
+            AlgorithmMap["SHA-384/PLAIN-ECDSA"] = "SHA-384withPLAIN-ECDSA";
+            AlgorithmMap["PLAIN-ECDSAWITHSHA384"] = "SHA-384withPLAIN-ECDSA";
+            AlgorithmMap["PLAIN-ECDSAWITHSHA-384"] = "SHA-384withPLAIN-ECDSA";
+            AlgorithmMap["SHA384WITHPLAIN-ECDSA"] = "SHA-384withPLAIN-ECDSA";
+            AlgorithmMap["SHA-384WITHPLAIN-ECDSA"] = "SHA-384withPLAIN-ECDSA";
+            AlgorithmMap[BsiObjectIdentifiers.ecdsa_plain_SHA384.Id] = "SHA-384withPLAIN-ECDSA";
+
+            AlgorithmMap["SHA512/PLAIN-ECDSA"] = "SHA-512withPLAIN-ECDSA";
+            AlgorithmMap["SHA-512/PLAIN-ECDSA"] = "SHA-512withPLAIN-ECDSA";
+            AlgorithmMap["PLAIN-ECDSAWITHSHA512"] = "SHA-512withPLAIN-ECDSA";
+            AlgorithmMap["PLAIN-ECDSAWITHSHA-512"] = "SHA-512withPLAIN-ECDSA";
+            AlgorithmMap["SHA512WITHPLAIN-ECDSA"] = "SHA-512withPLAIN-ECDSA";
+            AlgorithmMap["SHA-512WITHPLAIN-ECDSA"] = "SHA-512withPLAIN-ECDSA";
+            AlgorithmMap[BsiObjectIdentifiers.ecdsa_plain_SHA512.Id] = "SHA-512withPLAIN-ECDSA";
+
+            AlgorithmMap["RIPEMD160/PLAIN-ECDSA"] = "RIPEMD160withPLAIN-ECDSA";
+            AlgorithmMap["PLAIN-ECDSAWITHRIPEMD160"] = "RIPEMD160withPLAIN-ECDSA";
+            AlgorithmMap["RIPEMD160WITHPLAIN-ECDSA"] = "RIPEMD160withPLAIN-ECDSA";
+            AlgorithmMap[BsiObjectIdentifiers.ecdsa_plain_RIPEMD160.Id] = "RIPEMD160withPLAIN-ECDSA";
+
+            AlgorithmMap["SHA1WITHECNR"] = "SHA-1withECNR";
+            AlgorithmMap["SHA-1WITHECNR"] = "SHA-1withECNR";
+            AlgorithmMap["SHA224WITHECNR"] = "SHA-224withECNR";
+            AlgorithmMap["SHA-224WITHECNR"] = "SHA-224withECNR";
+            AlgorithmMap["SHA256WITHECNR"] = "SHA-256withECNR";
+            AlgorithmMap["SHA-256WITHECNR"] = "SHA-256withECNR";
+            AlgorithmMap["SHA384WITHECNR"] = "SHA-384withECNR";
+            AlgorithmMap["SHA-384WITHECNR"] = "SHA-384withECNR";
+            AlgorithmMap["SHA512WITHECNR"] = "SHA-512withECNR";
+            AlgorithmMap["SHA-512WITHECNR"] = "SHA-512withECNR";
+
+            AlgorithmMap["GOST-3410"] = "GOST3410";
+            AlgorithmMap["GOST-3410-94"] = "GOST3410";
+            AlgorithmMap["GOST3411WITHGOST3410"] = "GOST3410";
+            AlgorithmMap[CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94.Id] = "GOST3410";
+
+            AlgorithmMap["ECGOST-3410"] = "ECGOST3410";
+            AlgorithmMap["ECGOST-3410-2001"] = "ECGOST3410";
+            AlgorithmMap["GOST3411WITHECGOST3410"] = "ECGOST3410";
+            AlgorithmMap[CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001.Id] = "ECGOST3410";
+
+            AlgorithmMap["ED25519"] = "Ed25519";
+            AlgorithmMap[EdECObjectIdentifiers.id_Ed25519.Id] = "Ed25519";
+            AlgorithmMap["ED25519CTX"] = "Ed25519ctx";
+            AlgorithmMap["ED25519PH"] = "Ed25519ph";
+            AlgorithmMap["ED448"] = "Ed448";
+            AlgorithmMap[EdECObjectIdentifiers.id_Ed448.Id] = "Ed448";
+            AlgorithmMap["ED448PH"] = "Ed448ph";
+
+            AlgorithmMap["SHA256WITHSM2"] = "SHA256withSM2";
+            AlgorithmMap[GMObjectIdentifiers.sm2sign_with_sha256.Id] = "SHA256withSM2";
+            AlgorithmMap["SM3WITHSM2"] = "SM3withSM2";
+            AlgorithmMap[GMObjectIdentifiers.sm2sign_with_sm3.Id] = "SM3withSM2";
+
+            Oids["MD2withRSA"] = PkcsObjectIdentifiers.MD2WithRsaEncryption;
+            Oids["MD4withRSA"] = PkcsObjectIdentifiers.MD4WithRsaEncryption;
+            Oids["MD5withRSA"] = PkcsObjectIdentifiers.MD5WithRsaEncryption;
+
+            Oids["SHA-1withRSA"] = PkcsObjectIdentifiers.Sha1WithRsaEncryption;
+            Oids["SHA-224withRSA"] = PkcsObjectIdentifiers.Sha224WithRsaEncryption;
+            Oids["SHA-256withRSA"] = PkcsObjectIdentifiers.Sha256WithRsaEncryption;
+            Oids["SHA-384withRSA"] = PkcsObjectIdentifiers.Sha384WithRsaEncryption;
+            Oids["SHA-512withRSA"] = PkcsObjectIdentifiers.Sha512WithRsaEncryption;
+            Oids["SHA-512(224)withRSA"] = PkcsObjectIdentifiers.Sha512_224WithRSAEncryption;
+            Oids["SHA-512(256)withRSA"] = PkcsObjectIdentifiers.Sha512_256WithRSAEncryption;
+            Oids["SHA3-224withRSA"] = NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_224;
+            Oids["SHA3-256withRSA"] = NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_256;
+            Oids["SHA3-384withRSA"] = NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_384;
+            Oids["SHA3-512withRSA"] = NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_512;
+
+            Oids["PSSwithRSA"] = PkcsObjectIdentifiers.IdRsassaPss;
+            Oids["SHA-1withRSAandMGF1"] = PkcsObjectIdentifiers.IdRsassaPss;
+            Oids["SHA-224withRSAandMGF1"] = PkcsObjectIdentifiers.IdRsassaPss;
+            Oids["SHA-256withRSAandMGF1"] = PkcsObjectIdentifiers.IdRsassaPss;
+            Oids["SHA-384withRSAandMGF1"] = PkcsObjectIdentifiers.IdRsassaPss;
+            Oids["SHA-512withRSAandMGF1"] = PkcsObjectIdentifiers.IdRsassaPss;
+
+            Oids["RIPEMD128withRSA"] = TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128;
+            Oids["RIPEMD160withRSA"] = TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160;
+            Oids["RIPEMD256withRSA"] = TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256;
+
+            Oids["SHA-1withDSA"] = X9ObjectIdentifiers.IdDsaWithSha1;
+
+            Oids["SHA-1withECDSA"] = X9ObjectIdentifiers.ECDsaWithSha1;
+            Oids["SHA-224withECDSA"] = X9ObjectIdentifiers.ECDsaWithSha224;
+            Oids["SHA-256withECDSA"] = X9ObjectIdentifiers.ECDsaWithSha256;
+            Oids["SHA-384withECDSA"] = X9ObjectIdentifiers.ECDsaWithSha384;
+            Oids["SHA-512withECDSA"] = X9ObjectIdentifiers.ECDsaWithSha512;
+            Oids["RIPEMD160withECDSA"] = TeleTrusTObjectIdentifiers.ECSignWithRipeMD160;
+
+            Oids["SHA-1withCVC-ECDSA"] = EacObjectIdentifiers.id_TA_ECDSA_SHA_1;
+            Oids["SHA-224withCVC-ECDSA"] = EacObjectIdentifiers.id_TA_ECDSA_SHA_224;
+            Oids["SHA-256withCVC-ECDSA"] = EacObjectIdentifiers.id_TA_ECDSA_SHA_256;
+            Oids["SHA-384withCVC-ECDSA"] = EacObjectIdentifiers.id_TA_ECDSA_SHA_384;
+            Oids["SHA-512withCVC-ECDSA"] = EacObjectIdentifiers.id_TA_ECDSA_SHA_512;
+
+            Oids["SHA-1withPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_SHA1;
+            Oids["SHA-224withPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_SHA224;
+            Oids["SHA-256withPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_SHA256;
+            Oids["SHA-384withPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_SHA384;
+            Oids["SHA-512withPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_SHA512;
+            Oids["RIPEMD160withPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_RIPEMD160;
+
+            Oids["GOST3410"] = CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94;
+            Oids["ECGOST3410"] = CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001;
+
+            Oids["Ed25519"] = EdECObjectIdentifiers.id_Ed25519;
+            Oids["Ed448"] = EdECObjectIdentifiers.id_Ed448;
+
+            Oids["SHA256withSM2"] = GMObjectIdentifiers.sm2sign_with_sha256;
+            Oids["SM3withSM2"] = GMObjectIdentifiers.sm2sign_with_sm3;
         }
 
         /// <summary>
@@ -455,44 +452,32 @@ namespace Org.BouncyCastle.Security
         /// <param name="mechanism">A string representation of the encoding.</param>
         /// <returns>A DerObjectIdentifier, null if the OID is not available.</returns>
         // TODO Don't really want to support this
-        public static DerObjectIdentifier GetObjectIdentifier(
-            string mechanism)
+        public static DerObjectIdentifier GetObjectIdentifier(string mechanism)
         {
             if (mechanism == null)
-                throw new ArgumentNullException("mechanism");
+                throw new ArgumentNullException(nameof(mechanism));
 
-            mechanism = Platform.ToUpperInvariant(mechanism);
-            string aliased = (string) algorithms[mechanism];
+            string algorithm = CollectionUtilities.GetValueOrKey(AlgorithmMap, mechanism);
 
-            if (aliased != null)
-                mechanism = aliased;
-
-            return (DerObjectIdentifier) oids[mechanism];
+            return CollectionUtilities.GetValueOrNull(Oids, algorithm);
         }
 
-        public static ICollection Algorithms
+        public static ICollection<string> Algorithms
         {
-            get { return oids.Keys; }
+            get { return CollectionUtilities.ReadOnly(Oids.Keys); }
         }
 
-        public static Asn1Encodable GetDefaultX509Parameters(
-            DerObjectIdentifier id)
+        public static Asn1Encodable GetDefaultX509Parameters(DerObjectIdentifier id)
         {
             return GetDefaultX509Parameters(id.Id);
         }
 
-        public static Asn1Encodable GetDefaultX509Parameters(
-            string algorithm)
+        public static Asn1Encodable GetDefaultX509Parameters(string algorithm)
         {
             if (algorithm == null)
-                throw new ArgumentNullException("algorithm");
-
-            algorithm = Platform.ToUpperInvariant(algorithm);
+                throw new ArgumentNullException(nameof(algorithm));
 
-            string mechanism = (string) algorithms[algorithm];
-
-            if (mechanism == null)
-                mechanism = algorithm;
+            string mechanism = CollectionUtilities.GetValueOrKey(AlgorithmMap, algorithm);
 
             if (mechanism == "PSSwithRSA")
             {
@@ -525,24 +510,17 @@ namespace Org.BouncyCastle.Security
                 new DerInteger(saltLen), new DerInteger(1));
         }
 
-        public static ISigner GetSigner(
-            DerObjectIdentifier id)
+        public static ISigner GetSigner(DerObjectIdentifier id)
         {
             return GetSigner(id.Id);
         }
 
-        public static ISigner GetSigner(
-            string algorithm)
+        public static ISigner GetSigner(string algorithm)
         {
             if (algorithm == null)
-                throw new ArgumentNullException("algorithm");
-
-            algorithm = Platform.ToUpperInvariant(algorithm);
+                throw new ArgumentNullException(nameof(algorithm));
 
-            string mechanism = (string) algorithms[algorithm];
-
-            if (mechanism == null)
-                mechanism = algorithm;
+            string mechanism = CollectionUtilities.GetValueOrKey(AlgorithmMap, algorithm.ToUpperInvariant());
 
             if (Platform.StartsWith(mechanism, "Ed"))
             {
@@ -677,10 +655,9 @@ namespace Org.BouncyCastle.Security
             throw new SecurityUtilityException("Signer " + algorithm + " not recognised.");
         }
 
-        public static string GetEncodingName(
-            DerObjectIdentifier oid)
+        public static string GetEncodingName(DerObjectIdentifier oid)
         {
-            return (string) algorithms[oid.Id];
+            return CollectionUtilities.GetValueOrNull(AlgorithmMap, oid.Id);
         }
 
         public static ISigner InitSigner(DerObjectIdentifier algorithmOid, bool forSigning, AsymmetricKeyParameter privateKey, SecureRandom random)
diff --git a/crypto/src/security/WrapperUtilities.cs b/crypto/src/security/WrapperUtilities.cs
index c57632081..983ff824c 100644
--- a/crypto/src/security/WrapperUtilities.cs
+++ b/crypto/src/security/WrapperUtilities.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.Kisa;
@@ -9,61 +9,50 @@ using Org.BouncyCastle.Asn1.Pkcs;
 using Org.BouncyCastle.Crypto;
 using Org.BouncyCastle.Crypto.Engines;
 using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Collections;
 
 namespace Org.BouncyCastle.Security
 {
     /// <remarks>
     ///  Utility class for creating IWrapper objects from their names/Oids
     /// </remarks>
-    public sealed class WrapperUtilities
+    public static class WrapperUtilities
     {
         private enum WrapAlgorithm { AESWRAP, CAMELLIAWRAP, DESEDEWRAP, RC2WRAP, SEEDWRAP,
             DESEDERFC3211WRAP, AESRFC3211WRAP, CAMELLIARFC3211WRAP };
 
-        private WrapperUtilities()
-        {
-        }
-
-        private static readonly IDictionary algorithms = Platform.CreateHashtable();
-        //private static readonly IDictionary oids = Platform.CreateHashtable();
+        private static readonly IDictionary<string, string> Algorithms =
+            new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
 
         static WrapperUtilities()
         {
             // Signal to obfuscation tools not to change enum constants
             ((WrapAlgorithm)Enums.GetArbitraryValue(typeof(WrapAlgorithm))).ToString();
 
-            algorithms[NistObjectIdentifiers.IdAes128Wrap.Id] = "AESWRAP";
-            algorithms[NistObjectIdentifiers.IdAes192Wrap.Id] = "AESWRAP";
-            algorithms[NistObjectIdentifiers.IdAes256Wrap.Id] = "AESWRAP";
+            Algorithms[NistObjectIdentifiers.IdAes128Wrap.Id] = "AESWRAP";
+            Algorithms[NistObjectIdentifiers.IdAes192Wrap.Id] = "AESWRAP";
+            Algorithms[NistObjectIdentifiers.IdAes256Wrap.Id] = "AESWRAP";
 
-            algorithms[NttObjectIdentifiers.IdCamellia128Wrap.Id] = "CAMELLIAWRAP";
-            algorithms[NttObjectIdentifiers.IdCamellia192Wrap.Id] = "CAMELLIAWRAP";
-            algorithms[NttObjectIdentifiers.IdCamellia256Wrap.Id] = "CAMELLIAWRAP";
+            Algorithms[NttObjectIdentifiers.IdCamellia128Wrap.Id] = "CAMELLIAWRAP";
+            Algorithms[NttObjectIdentifiers.IdCamellia192Wrap.Id] = "CAMELLIAWRAP";
+            Algorithms[NttObjectIdentifiers.IdCamellia256Wrap.Id] = "CAMELLIAWRAP";
 
-            algorithms[PkcsObjectIdentifiers.IdAlgCms3DesWrap.Id] = "DESEDEWRAP";
-            algorithms["TDEAWRAP"] = "DESEDEWRAP";
+            Algorithms[PkcsObjectIdentifiers.IdAlgCms3DesWrap.Id] = "DESEDEWRAP";
+            Algorithms["TDEAWRAP"] = "DESEDEWRAP";
 
-            algorithms[PkcsObjectIdentifiers.IdAlgCmsRC2Wrap.Id] = "RC2WRAP";
+            Algorithms[PkcsObjectIdentifiers.IdAlgCmsRC2Wrap.Id] = "RC2WRAP";
 
-            algorithms[KisaObjectIdentifiers.IdNpkiAppCmsSeedWrap.Id] = "SEEDWRAP";
+            Algorithms[KisaObjectIdentifiers.IdNpkiAppCmsSeedWrap.Id] = "SEEDWRAP";
         }
 
-        public static IWrapper GetWrapper(
-            DerObjectIdentifier oid)
+        public static IWrapper GetWrapper(DerObjectIdentifier oid)
         {
             return GetWrapper(oid.Id);
         }
 
-        public static IWrapper GetWrapper(
-            string algorithm)
+        public static IWrapper GetWrapper(string algorithm)
         {
-            string upper = Platform.ToUpperInvariant(algorithm);
-            string mechanism = (string)algorithms[upper];
-
-            if (mechanism == null)
-            {
-                mechanism = upper;
-            }
+            string mechanism = CollectionUtilities.GetValueOrKey(Algorithms, algorithm).ToUpperInvariant();
 
             try
             {
@@ -72,14 +61,14 @@ namespace Org.BouncyCastle.Security
 
                 switch (wrapAlgorithm)
                 {
-                    case WrapAlgorithm.AESWRAP:				return new AesWrapEngine();
-                    case WrapAlgorithm.CAMELLIAWRAP:		return new CamelliaWrapEngine();
-                    case WrapAlgorithm.DESEDEWRAP:			return new DesEdeWrapEngine();
-                    case WrapAlgorithm.RC2WRAP:				return new RC2WrapEngine();
-                    case WrapAlgorithm.SEEDWRAP:			return new SeedWrapEngine();
-                    case WrapAlgorithm.DESEDERFC3211WRAP:	return new Rfc3211WrapEngine(new DesEdeEngine());
-                    case WrapAlgorithm.AESRFC3211WRAP:		return new Rfc3211WrapEngine(new AesEngine());
-                    case WrapAlgorithm.CAMELLIARFC3211WRAP:	return new Rfc3211WrapEngine(new CamelliaEngine());
+                case WrapAlgorithm.AESWRAP:				return new AesWrapEngine();
+                case WrapAlgorithm.CAMELLIAWRAP:		return new CamelliaWrapEngine();
+                case WrapAlgorithm.DESEDEWRAP:			return new DesEdeWrapEngine();
+                case WrapAlgorithm.RC2WRAP:				return new RC2WrapEngine();
+                case WrapAlgorithm.SEEDWRAP:			return new SeedWrapEngine();
+                case WrapAlgorithm.DESEDERFC3211WRAP:	return new Rfc3211WrapEngine(new DesEdeEngine());
+                case WrapAlgorithm.AESRFC3211WRAP:		return new Rfc3211WrapEngine(new AesEngine());
+                case WrapAlgorithm.CAMELLIARFC3211WRAP:	return new Rfc3211WrapEngine(new CamelliaEngine());
                 }
             }
             catch (ArgumentException)
@@ -95,10 +84,9 @@ namespace Org.BouncyCastle.Security
             throw new SecurityUtilityException("Wrapper " + algorithm + " not recognised.");
         }
 
-        public static string GetAlgorithmName(
-            DerObjectIdentifier oid)
+        public static string GetAlgorithmName(DerObjectIdentifier oid)
         {
-            return (string) algorithms[oid.Id];
+            return CollectionUtilities.GetValueOrNull(Algorithms, oid.Id);
         }
 
         private class BufferedCipherWrapper
diff --git a/crypto/src/tsp/TSPAlgorithms.cs b/crypto/src/tsp/TSPAlgorithms.cs
index 928468ed7..8d7e12ee4 100644
--- a/crypto/src/tsp/TSPAlgorithms.cs
+++ b/crypto/src/tsp/TSPAlgorithms.cs
@@ -1,4 +1,4 @@
-using System.Collections;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Asn1.CryptoPro;
 using Org.BouncyCastle.Asn1.GM;
@@ -35,20 +35,15 @@ namespace Org.BouncyCastle.Tsp
 
         public static readonly string SM3 = GMObjectIdentifiers.sm3.Id;
 
-        public static readonly IList Allowed;
+        public static readonly List<string> Allowed;
 
 		static TspAlgorithms()
 		{
-			string[] algs = new string[]
+			Allowed = new List<string>()
 			{
-				Gost3411, Gost3411_2012_256, Gost3411_2012_512, MD5, RipeMD128, RipeMD160, RipeMD256, Sha1, Sha224, Sha256, Sha384, Sha512, SM3
+				Gost3411, Gost3411_2012_256, Gost3411_2012_512, MD5, RipeMD128, RipeMD160, RipeMD256, Sha1, Sha224,
+				Sha256, Sha384, Sha512, SM3
 			};
-
-			Allowed = Platform.CreateArrayList();
-			foreach (string alg in algs)
-			{
-				Allowed.Add(alg);
-			}
 		}
 	}
 }
diff --git a/crypto/src/tsp/TSPUtil.cs b/crypto/src/tsp/TSPUtil.cs
index 34ff53b60..a9402ac6d 100644
--- a/crypto/src/tsp/TSPUtil.cs
+++ b/crypto/src/tsp/TSPUtil.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 using Org.BouncyCastle.Asn1;
@@ -22,50 +22,47 @@ namespace Org.BouncyCastle.Tsp
 {
 	public class TspUtil
 	{
-		private static ISet EmptySet = CollectionUtilities.ReadOnly(new HashSet());
-		private static IList EmptyList = CollectionUtilities.ReadOnly(Platform.CreateArrayList());
-
-		private static readonly IDictionary digestLengths = Platform.CreateHashtable();
-        private static readonly IDictionary digestNames = Platform.CreateHashtable();
+		private static readonly Dictionary<string, int> DigestLengths = new Dictionary<string, int>();
+        private static readonly Dictionary<string, string> DigestNames = new Dictionary<string, string>();
 
 		static TspUtil()
 		{
-            digestLengths.Add(PkcsObjectIdentifiers.MD5.Id, 16);
-            digestLengths.Add(OiwObjectIdentifiers.IdSha1.Id, 20);
-            digestLengths.Add(NistObjectIdentifiers.IdSha224.Id, 28);
-            digestLengths.Add(NistObjectIdentifiers.IdSha256.Id, 32);
-            digestLengths.Add(NistObjectIdentifiers.IdSha384.Id, 48);
-            digestLengths.Add(NistObjectIdentifiers.IdSha512.Id, 64);
-            digestLengths.Add(TeleTrusTObjectIdentifiers.RipeMD128.Id, 16);
-            digestLengths.Add(TeleTrusTObjectIdentifiers.RipeMD160.Id, 20);
-            digestLengths.Add(TeleTrusTObjectIdentifiers.RipeMD256.Id, 32);
-            digestLengths.Add(CryptoProObjectIdentifiers.GostR3411.Id, 32);
-            digestLengths.Add(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256.Id, 32);
-            digestLengths.Add(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512.Id, 64);
-            digestLengths.Add(GMObjectIdentifiers.sm3.Id, 32);
-
-            digestNames.Add(PkcsObjectIdentifiers.MD5.Id, "MD5");
-            digestNames.Add(OiwObjectIdentifiers.IdSha1.Id, "SHA1");
-            digestNames.Add(NistObjectIdentifiers.IdSha224.Id, "SHA224");
-            digestNames.Add(NistObjectIdentifiers.IdSha256.Id, "SHA256");
-            digestNames.Add(NistObjectIdentifiers.IdSha384.Id, "SHA384");
-            digestNames.Add(NistObjectIdentifiers.IdSha512.Id, "SHA512");
-            digestNames.Add(PkcsObjectIdentifiers.MD5WithRsaEncryption.Id, "MD5");
-			digestNames.Add(PkcsObjectIdentifiers.Sha1WithRsaEncryption.Id, "SHA1");
-            digestNames.Add(PkcsObjectIdentifiers.Sha224WithRsaEncryption.Id, "SHA224");
-            digestNames.Add(PkcsObjectIdentifiers.Sha256WithRsaEncryption.Id, "SHA256");
-            digestNames.Add(PkcsObjectIdentifiers.Sha384WithRsaEncryption.Id, "SHA384");
-            digestNames.Add(PkcsObjectIdentifiers.Sha512WithRsaEncryption.Id, "SHA512");
-            digestNames.Add(TeleTrusTObjectIdentifiers.RipeMD128.Id, "RIPEMD128");
-            digestNames.Add(TeleTrusTObjectIdentifiers.RipeMD160.Id, "RIPEMD160");
-            digestNames.Add(TeleTrusTObjectIdentifiers.RipeMD256.Id, "RIPEMD256");
-            digestNames.Add(CryptoProObjectIdentifiers.GostR3411.Id, "GOST3411");
-            digestNames.Add(OiwObjectIdentifiers.DsaWithSha1.Id, "SHA1");
-            digestNames.Add(OiwObjectIdentifiers.Sha1WithRsa.Id, "SHA1");
-            digestNames.Add(OiwObjectIdentifiers.MD5WithRsa.Id, "MD5");
-            digestNames.Add(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256.Id, "GOST3411-2012-256");
-            digestNames.Add(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512.Id, "GOST3411-2012-512");
-            digestNames.Add(GMObjectIdentifiers.sm3.Id, "SM3");
+			DigestLengths.Add(PkcsObjectIdentifiers.MD5.Id, 16);
+            DigestLengths.Add(OiwObjectIdentifiers.IdSha1.Id, 20);
+            DigestLengths.Add(NistObjectIdentifiers.IdSha224.Id, 28);
+            DigestLengths.Add(NistObjectIdentifiers.IdSha256.Id, 32);
+            DigestLengths.Add(NistObjectIdentifiers.IdSha384.Id, 48);
+            DigestLengths.Add(NistObjectIdentifiers.IdSha512.Id, 64);
+            DigestLengths.Add(TeleTrusTObjectIdentifiers.RipeMD128.Id, 16);
+            DigestLengths.Add(TeleTrusTObjectIdentifiers.RipeMD160.Id, 20);
+            DigestLengths.Add(TeleTrusTObjectIdentifiers.RipeMD256.Id, 32);
+            DigestLengths.Add(CryptoProObjectIdentifiers.GostR3411.Id, 32);
+            DigestLengths.Add(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256.Id, 32);
+            DigestLengths.Add(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512.Id, 64);
+            DigestLengths.Add(GMObjectIdentifiers.sm3.Id, 32);
+
+            DigestNames.Add(PkcsObjectIdentifiers.MD5.Id, "MD5");
+            DigestNames.Add(OiwObjectIdentifiers.IdSha1.Id, "SHA1");
+            DigestNames.Add(NistObjectIdentifiers.IdSha224.Id, "SHA224");
+            DigestNames.Add(NistObjectIdentifiers.IdSha256.Id, "SHA256");
+            DigestNames.Add(NistObjectIdentifiers.IdSha384.Id, "SHA384");
+            DigestNames.Add(NistObjectIdentifiers.IdSha512.Id, "SHA512");
+            DigestNames.Add(PkcsObjectIdentifiers.MD5WithRsaEncryption.Id, "MD5");
+			DigestNames.Add(PkcsObjectIdentifiers.Sha1WithRsaEncryption.Id, "SHA1");
+            DigestNames.Add(PkcsObjectIdentifiers.Sha224WithRsaEncryption.Id, "SHA224");
+            DigestNames.Add(PkcsObjectIdentifiers.Sha256WithRsaEncryption.Id, "SHA256");
+            DigestNames.Add(PkcsObjectIdentifiers.Sha384WithRsaEncryption.Id, "SHA384");
+            DigestNames.Add(PkcsObjectIdentifiers.Sha512WithRsaEncryption.Id, "SHA512");
+            DigestNames.Add(TeleTrusTObjectIdentifiers.RipeMD128.Id, "RIPEMD128");
+            DigestNames.Add(TeleTrusTObjectIdentifiers.RipeMD160.Id, "RIPEMD160");
+            DigestNames.Add(TeleTrusTObjectIdentifiers.RipeMD256.Id, "RIPEMD256");
+            DigestNames.Add(CryptoProObjectIdentifiers.GostR3411.Id, "GOST3411");
+            DigestNames.Add(OiwObjectIdentifiers.DsaWithSha1.Id, "SHA1");
+            DigestNames.Add(OiwObjectIdentifiers.Sha1WithRsa.Id, "SHA1");
+            DigestNames.Add(OiwObjectIdentifiers.MD5WithRsa.Id, "MD5");
+            DigestNames.Add(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256.Id, "GOST3411-2012-256");
+            DigestNames.Add(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512.Id, "GOST3411-2012-512");
+            DigestNames.Add(GMObjectIdentifiers.sm3.Id, "SM3");
         }
 
 
@@ -78,10 +75,10 @@ namespace Org.BouncyCastle.Tsp
 	     * @return a collection of TimeStampToken objects
 	     * @throws TSPValidationException
 	     */
-		public static ICollection GetSignatureTimestamps(
+		public static IList<TimeStampToken> GetSignatureTimestamps(
 			SignerInformation signerInfo)
 		{
-			IList timestamps = Platform.CreateArrayList();
+			var timestamps = new List<TimeStampToken>();
 
 			Asn1.Cms.AttributeTable unsignedAttrs = signerInfo.UnsignedAttributes;
 			if (unsignedAttrs != null)
@@ -161,54 +158,45 @@ namespace Org.BouncyCastle.Tsp
 		/// Return the digest algorithm using one of the standard JCA string
 		/// representations rather than the algorithm identifier (if possible).
 		/// </summary>
-		internal static string GetDigestAlgName(
-			string digestAlgOID)
+		internal static string GetDigestAlgName(string digestAlgOid)
 		{
-			string digestName = (string) digestNames[digestAlgOID];
-
-			return digestName != null ? digestName : digestAlgOID;
+			return CollectionUtilities.GetValueOrKey(DigestNames, digestAlgOid);
 		}
 
-		internal static int GetDigestLength(
-			string digestAlgOID)
+		internal static int GetDigestLength(string digestAlgOid)
 		{
-			if (!digestLengths.Contains(digestAlgOID))
+			if (!DigestLengths.TryGetValue(digestAlgOid, out int length))
 				throw new TspException("digest algorithm cannot be found.");
 
-			return (int)digestLengths[digestAlgOID];
+			return length;
 		}
 
-		internal static IDigest CreateDigestInstance(
-			string digestAlgOID)
+		internal static IDigest CreateDigestInstance(string digestAlgOID)
 		{
 	        string digestName = GetDigestAlgName(digestAlgOID);
 
 			return DigestUtilities.GetDigest(digestName);
 		}
 
-		internal static ISet GetCriticalExtensionOids(X509Extensions extensions)
+		internal static ISet<DerObjectIdentifier> GetCriticalExtensionOids(X509Extensions extensions)
 		{
-			if (extensions == null)
-				return EmptySet;
-
-			return CollectionUtilities.ReadOnly(new HashSet(extensions.GetCriticalExtensionOids()));
+			return extensions == null
+				? new HashSet<DerObjectIdentifier>()
+				: new HashSet<DerObjectIdentifier>(extensions.GetCriticalExtensionOids());
 		}
 
-		internal static ISet GetNonCriticalExtensionOids(X509Extensions extensions)
+		internal static ISet<DerObjectIdentifier> GetNonCriticalExtensionOids(X509Extensions extensions)
 		{
-			if (extensions == null)
-				return EmptySet;
-
-			// TODO: should probably produce a set that imposes correct ordering
-			return CollectionUtilities.ReadOnly(new HashSet(extensions.GetNonCriticalExtensionOids()));
+			return extensions == null
+				? new HashSet<DerObjectIdentifier>()
+				: new HashSet<DerObjectIdentifier>(extensions.GetNonCriticalExtensionOids());
 		}
-		
-		internal static IList GetExtensionOids(X509Extensions extensions)
-		{
-			if (extensions == null)
-				return EmptyList;
 
-			return CollectionUtilities.ReadOnly(Platform.CreateArrayList(extensions.GetExtensionOids()));
+		internal static IList<DerObjectIdentifier> GetExtensionOids(X509Extensions extensions)
+		{
+			return extensions == null
+				? new List<DerObjectIdentifier>()
+				: new List<DerObjectIdentifier>(extensions.GetExtensionOids());
 		}
 	}
 }
diff --git a/crypto/src/tsp/TimeStampRequest.cs b/crypto/src/tsp/TimeStampRequest.cs
index f5c6a09e6..b05b58c0e 100644
--- a/crypto/src/tsp/TimeStampRequest.cs
+++ b/crypto/src/tsp/TimeStampRequest.cs
@@ -1,14 +1,12 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.Cmp;
 using Org.BouncyCastle.Asn1.Tsp;
 using Org.BouncyCastle.Asn1.X509;
-using Org.BouncyCastle.Crypto;
 using Org.BouncyCastle.Math;
-using Org.BouncyCastle.Security;
 using Org.BouncyCastle.X509;
 
 namespace Org.BouncyCastle.Tsp
@@ -124,10 +122,7 @@ namespace Org.BouncyCastle.Tsp
 		* @param extensions if non-null a set of extensions we are willing to accept.
 		* @throws TspException if the request is invalid, or processing fails.
 		*/
-		public void Validate(
-			IList algorithms,
-			IList policies,
-			IList extensions)
+		public void Validate(IList<string> algorithms, IList<string> policies, IList<string> extensions)
 		{
 			if (!algorithms.Contains(this.MessageImprintAlgOid))
 				throw new TspValidationException("request contains unknown algorithm", PkiFailureInfo.BadAlg);
@@ -173,7 +168,7 @@ namespace Org.BouncyCastle.Tsp
 			return extensions == null ? null : extensions.GetExtension(oid);
 		}
 
-		public virtual IList GetExtensionOids()
+		public virtual IList<DerObjectIdentifier> GetExtensionOids()
 		{
 			return TspUtil.GetExtensionOids(extensions);
 		}
diff --git a/crypto/src/tsp/TimeStampResponseGenerator.cs b/crypto/src/tsp/TimeStampResponseGenerator.cs
index a88320027..9a9c78678 100644
--- a/crypto/src/tsp/TimeStampResponseGenerator.cs
+++ b/crypto/src/tsp/TimeStampResponseGenerator.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 using Org.BouncyCastle.Asn1;
@@ -23,30 +23,30 @@ namespace Org.BouncyCastle.Tsp
 
         private int failInfo;
         private TimeStampTokenGenerator tokenGenerator;
-        private IList acceptedAlgorithms;
-        private IList acceptedPolicies;
-        private IList acceptedExtensions;
+        private IList<string> acceptedAlgorithms;
+        private IList<string> acceptedPolicies;
+        private IList<string> acceptedExtensions;
 
         public TimeStampResponseGenerator(
             TimeStampTokenGenerator tokenGenerator,
-            IList acceptedAlgorithms)
+            IList<string> acceptedAlgorithms)
             : this(tokenGenerator, acceptedAlgorithms, null, null)
         {
         }
 
         public TimeStampResponseGenerator(
             TimeStampTokenGenerator tokenGenerator,
-            IList acceptedAlgorithms,
-            IList acceptedPolicy)
+            IList<string> acceptedAlgorithms,
+            IList<string> acceptedPolicy)
             : this(tokenGenerator, acceptedAlgorithms, acceptedPolicy, null)
         {
         }
 
         public TimeStampResponseGenerator(
             TimeStampTokenGenerator tokenGenerator,
-            IList acceptedAlgorithms,
-            IList acceptedPolicies,
-            IList acceptedExtensions)
+            IList<string> acceptedAlgorithms,
+            IList<string> acceptedPolicies,
+            IList<string> acceptedExtensions)
         {
             this.tokenGenerator = tokenGenerator;
             this.acceptedAlgorithms = acceptedAlgorithms;
diff --git a/crypto/src/tsp/TimeStampToken.cs b/crypto/src/tsp/TimeStampToken.cs
index 2b7187cad..93b372720 100644
--- a/crypto/src/tsp/TimeStampToken.cs
+++ b/crypto/src/tsp/TimeStampToken.cs
@@ -1,5 +1,4 @@
 using System;
-using System.Collections;
 using System.IO;
 
 using Org.BouncyCastle.Asn1;
@@ -52,10 +51,10 @@ namespace Org.BouncyCastle.Tsp
 			}
 
 
-			IEnumerator signerEnum = signers.GetEnumerator();
+			var signerEnum = signers.GetEnumerator();
 
 			signerEnum.MoveNext();
-			tsaSignerInfo = (SignerInformation) signerEnum.Current;
+			tsaSignerInfo = signerEnum.Current;
 
 			try
 			{
diff --git a/crypto/src/tsp/TimeStampTokenGenerator.cs b/crypto/src/tsp/TimeStampTokenGenerator.cs
index 4289d7d24..0d6d102d3 100644
--- a/crypto/src/tsp/TimeStampTokenGenerator.cs
+++ b/crypto/src/tsp/TimeStampTokenGenerator.cs
@@ -1,5 +1,4 @@
 using System;
-using System.Collections;
 using System.Collections.Generic;
 using System.IO;
 using System.Text;
@@ -39,7 +38,7 @@ namespace Org.BouncyCastle.Tsp
         private IStore<X509Crl> x509Crls;
         private IStore<X509V2AttributeCertificate> x509AttrCerts;
         // TODO Port changes from bc-java
-        //private IDictionary otherRevoc = Platform.CreateHashtable();
+        //private Dictionary<> otherRevoc = new Dictionary<>();
         private SignerInfoGenerator signerInfoGenerator;
         IDigestFactory digestCalculator;
 
@@ -63,22 +62,18 @@ namespace Org.BouncyCastle.Tsp
         {
         }
 
-
         public TimeStampTokenGenerator(
             SignerInfoGenerator signerInfoGen,
             IDigestFactory digestCalculator,
             DerObjectIdentifier tsaPolicy,
             bool isIssuerSerialIncluded)
         {
-
             this.signerInfoGenerator = signerInfoGen;
             this.digestCalculator = digestCalculator;
             this.tsaPolicyOID = tsaPolicy;
 
             if (signerInfoGenerator.certificate == null)
-            {
                 throw new ArgumentException("SignerInfoGenerator must have an associated certificate");
-            }
 
             X509Certificate assocCert = signerInfoGenerator.certificate;
             TspUtil.ValidateCertificate(assocCert);
@@ -123,7 +118,6 @@ namespace Org.BouncyCastle.Tsp
                         .WithSignedAttributeGenerator(new TableGen2(signerInfoGen, essCertID))
                         .Build(signerInfoGen.contentSigner, signerInfoGen.certificate);
                 }
-
             }
             catch (Exception ex)
             {
@@ -147,17 +141,13 @@ namespace Org.BouncyCastle.Tsp
         {
         }
 
-
         internal static SignerInfoGenerator makeInfoGenerator(
           AsymmetricKeyParameter key,
           X509Certificate cert,
           string digestOID,
-
           Asn1.Cms.AttributeTable signedAttr,
           Asn1.Cms.AttributeTable unsignedAttr)
         {
-
-
             TspUtil.ValidateCertificate(cert);
 
             //
@@ -194,7 +184,6 @@ namespace Org.BouncyCastle.Tsp
             //    throw new TspException("Can't find a SHA-1 implementation.", e);
             //}
 
-
             string digestName = CmsSignedHelper.Instance.GetDigestAlgName(digestOID);
             string signatureName = digestName + "with" + CmsSignedHelper.Instance.GetEncryptionAlgName(CmsSignedHelper.Instance.GetEncOid(key, digestOID));
 
diff --git a/crypto/src/util/Platform.cs b/crypto/src/util/Platform.cs
index f0b2406a5..b25d76dae 100644
--- a/crypto/src/util/Platform.cs
+++ b/crypto/src/util/Platform.cs
@@ -1,12 +1,6 @@
 using System;
 using System.Globalization;
 
-#if PORTABLE
-using System.Collections.Generic;
-#else
-using System.Collections;
-#endif
-
 namespace Org.BouncyCastle.Utilities
 {
     internal abstract class Platform
@@ -32,107 +26,11 @@ namespace Org.BouncyCastle.Utilities
             }
         }
 
-        internal static Exception CreateNotImplementedException(
-            string message)
-        {
-            return new NotImplementedException(message);
-        }
-
-#if PORTABLE
-        internal static System.Collections.IList CreateArrayList()
-        {
-            return new List<object>();
-        }
-        internal static System.Collections.IList CreateArrayList(int capacity)
-        {
-            return new List<object>(capacity);
-        }
-        internal static System.Collections.IList CreateArrayList(System.Collections.ICollection collection)
-        {
-            System.Collections.IList result = new List<object>(collection.Count);
-            foreach (object o in collection)
-            {
-                result.Add(o);
-            }
-            return result;
-        }
-        internal static System.Collections.IList CreateArrayList(System.Collections.IEnumerable collection)
-        {
-            System.Collections.IList result = new List<object>();
-            foreach (object o in collection)
-            {
-                result.Add(o);
-            }
-            return result;
-        }
-        internal static System.Collections.IDictionary CreateHashtable()
-        {
-            return new Dictionary<object, object>();
-        }
-        internal static System.Collections.IDictionary CreateHashtable(int capacity)
-        {
-            return new Dictionary<object, object>(capacity);
-        }
-        internal static System.Collections.IDictionary CreateHashtable(System.Collections.IDictionary dictionary)
-        {
-            System.Collections.IDictionary result = new Dictionary<object, object>(dictionary.Count);
-            foreach (System.Collections.DictionaryEntry entry in dictionary)
-            {
-                result.Add(entry.Key, entry.Value);
-            }
-            return result;
-        }
-#else
-        internal static System.Collections.IList CreateArrayList()
-        {
-            return new ArrayList();
-        }
-        internal static System.Collections.IList CreateArrayList(int capacity)
-        {
-            return new ArrayList(capacity);
-        }
-        internal static System.Collections.IList CreateArrayList(System.Collections.ICollection collection)
-        {
-            return new ArrayList(collection);
-        }
-        internal static System.Collections.IList CreateArrayList(System.Collections.IEnumerable collection)
-        {
-            ArrayList result = new ArrayList();
-            foreach (object o in collection)
-            {
-                result.Add(o);
-            }
-            return result;
-        }
-        internal static System.Collections.IDictionary CreateHashtable()
-        {
-            return new Hashtable();
-        }
-        internal static System.Collections.IDictionary CreateHashtable(int capacity)
-        {
-            return new Hashtable(capacity);
-        }
-        internal static System.Collections.IDictionary CreateHashtable(System.Collections.IDictionary dictionary)
-        {
-            return new Hashtable(dictionary);
-        }
-#endif
-
         internal static int GetHashCode(object obj)
         {
             return null == obj ? 0 : obj.GetHashCode();
         }
 
-        internal static string ToLowerInvariant(string s)
-        {
-            return s.ToLowerInvariant();
-        }
-
-        internal static string ToUpperInvariant(string s)
-        {
-            return s.ToUpperInvariant();
-        }
-
         internal static readonly string NewLine = Environment.NewLine;
 
         internal static void Dispose(IDisposable d)
diff --git a/crypto/src/util/collections/CollectionUtilities.cs b/crypto/src/util/collections/CollectionUtilities.cs
index 4a42cf19d..41b558130 100644
--- a/crypto/src/util/collections/CollectionUtilities.cs
+++ b/crypto/src/util/collections/CollectionUtilities.cs
@@ -1,5 +1,4 @@
 using System;
-using System.Collections;
 using System.Collections.Generic;
 using System.Text;
 
@@ -7,19 +6,6 @@ namespace Org.BouncyCastle.Utilities.Collections
 {
     public abstract class CollectionUtilities
     {
-        public static void AddRange(IList to, IEnumerable range)
-        {
-            foreach (object o in range)
-            {
-                to.Add(o);
-            }
-        }
-
-        public static void CollectMatches<T>(ICollection<T> matches, ISelector<T> selector, params IStore<T>[] stores)
-        {
-            CollectMatches(matches, selector, stores);
-        }
-
         public static void CollectMatches<T>(ICollection<T> matches, ISelector<T> selector,
             IEnumerable<IStore<T>> stores)
         {
@@ -45,6 +31,12 @@ namespace Org.BouncyCastle.Utilities.Collections
             return new StoreImpl<T>(contents);
         }
 
+        public static T GetValueOrKey<T>(IDictionary<T, T> d, T k)
+            where T : class
+        {
+            return d.TryGetValue(k, out var v) ? v : k;
+        }
+
         public static V GetValueOrNull<K, V>(IDictionary<K, V> d, K k)
             where V : class
         {
@@ -56,14 +48,14 @@ namespace Org.BouncyCastle.Utilities.Collections
             return new EnumerableProxy<T>(e);
         }
 
-        public static IDictionary ReadOnly(IDictionary d)
+        public static ICollection<T> ReadOnly<T>(ICollection<T> c)
         {
-            return new UnmodifiableDictionaryProxy(d);
+            return new ReadOnlyCollectionProxy<T>(c);
         }
 
-        public static IList ReadOnly(IList l)
+        public static IDictionary<K, V> ReadOnly<K, V>(IDictionary<K, V> d)
         {
-            return new UnmodifiableListProxy(l);
+            return new ReadOnlyDictionaryProxy<K, V>(d);
         }
 
         public static IList<T> ReadOnly<T>(IList<T> l)
@@ -71,9 +63,9 @@ namespace Org.BouncyCastle.Utilities.Collections
             return new ReadOnlyListProxy<T>(l);
         }
 
-        public static ISet ReadOnly(ISet s)
+        public static ISet<T> ReadOnly<T>(ISet<T> s)
         {
-            return new UnmodifiableSetProxy(s);
+            return new ReadOnlySetProxy<T>(s);
         }
 
         public static bool Remove<K, V>(IDictionary<K, V> d, K k, out V v)
@@ -85,7 +77,7 @@ namespace Org.BouncyCastle.Utilities.Collections
             return true;
         }
 
-        public static object RequireNext(IEnumerator e)
+        public static T RequireNext<T>(IEnumerator<T> e)
         {
             if (!e.MoveNext())
                 throw new InvalidOperationException();
diff --git a/crypto/src/util/collections/EmptyEnumerable.cs b/crypto/src/util/collections/EmptyEnumerable.cs
deleted file mode 100644
index a61a0789a..000000000
--- a/crypto/src/util/collections/EmptyEnumerable.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-using System;
-using System.Collections;
-
-namespace Org.BouncyCastle.Utilities.Collections
-{
-	public sealed class EmptyEnumerable
-		: IEnumerable
-	{
-		public static readonly IEnumerable Instance = new EmptyEnumerable();
-
-		private EmptyEnumerable()
-		{
-		}
-
-		public IEnumerator GetEnumerator()
-		{
-			return EmptyEnumerator.Instance;
-		}
-	}
-
-	public sealed class EmptyEnumerator
-		: IEnumerator
-	{
-		public static readonly IEnumerator Instance = new EmptyEnumerator();
-
-		private EmptyEnumerator()
-		{
-		}
-
-		public bool MoveNext()
-		{
-			return false;
-		}
-
-		public void Reset()
-		{
-		}
-
-		public object Current
-		{
-			get { throw new InvalidOperationException("No elements"); }
-		}
-	}
-}
diff --git a/crypto/src/util/collections/EnumerableProxy.cs b/crypto/src/util/collections/EnumerableProxy.cs
index 36f78d342..1d97b8f22 100644
--- a/crypto/src/util/collections/EnumerableProxy.cs
+++ b/crypto/src/util/collections/EnumerableProxy.cs
@@ -1,50 +1,29 @@
 using System;
-using System.Collections;
 using System.Collections.Generic;
 
 namespace Org.BouncyCastle.Utilities.Collections
 {
-	public sealed class EnumerableProxy
-		: IEnumerable
-	{
-		private readonly IEnumerable inner;
-
-		public EnumerableProxy(
-			IEnumerable inner)
-		{
-			if (inner == null)
-				throw new ArgumentNullException("inner");
-
-			this.inner = inner;
-		}
-
-		public IEnumerator GetEnumerator()
-		{
-			return inner.GetEnumerator();
-		}
-	}
-
 	internal sealed class EnumerableProxy<T>
 		: IEnumerable<T>
 	{
-		private readonly IEnumerable<T> m_inner;
+		private readonly IEnumerable<T> m_target;
 
-		internal EnumerableProxy(IEnumerable<T> inner)
+		internal EnumerableProxy(IEnumerable<T> target)
 		{
-			if (inner == null)
-				throw new ArgumentNullException("inner");
+			if (target == null)
+				throw new ArgumentNullException(nameof(target));
 
-			m_inner = inner;
+			m_target = target;
 		}
 
 		System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
 		{
-			return m_inner.GetEnumerator();
+			return m_target.GetEnumerator();
 		}
 
 		public IEnumerator<T> GetEnumerator()
 		{
-			return m_inner.GetEnumerator();
+			return m_target.GetEnumerator();
 		}
 	}
 }
diff --git a/crypto/src/util/collections/HashSet.cs b/crypto/src/util/collections/HashSet.cs
deleted file mode 100644
index 1facb58e3..000000000
--- a/crypto/src/util/collections/HashSet.cs
+++ /dev/null
@@ -1,99 +0,0 @@
-using System;
-using System.Collections;
-
-namespace Org.BouncyCastle.Utilities.Collections
-{
-	public class HashSet
-		: ISet
-	{
-		private readonly IDictionary impl = Platform.CreateHashtable();
-
-		public HashSet()
-		{
-		}
-
-		public HashSet(IEnumerable s)
-		{
-			foreach (object o in s)
-			{
-				Add(o);
-			}
-		}
-
-		public virtual void Add(object o)
-		{
-			impl[o] = null;
-		}
-
-		public virtual void AddAll(IEnumerable e)
-		{
-			foreach (object o in e)
-			{
-				Add(o);
-			}
-		}
-
-		public virtual void Clear()
-		{
-			impl.Clear();
-		}
-
-		public virtual bool Contains(object o)
-		{
-			return impl.Contains(o);
-		}
-
-		public virtual void CopyTo(Array array, int index)
-		{
-			impl.Keys.CopyTo(array, index);
-		}
-
-		public virtual int Count
-		{
-			get { return impl.Count; }
-		}
-
-		public virtual IEnumerator GetEnumerator()
-		{
-			return impl.Keys.GetEnumerator();
-		}
-
-		public virtual bool IsEmpty
-		{
-			get { return impl.Count == 0; }
-		}
-
-		public virtual bool IsFixedSize
-		{
-			get { return impl.IsFixedSize; }
-		}
-
-		public virtual bool IsReadOnly
-		{
-			get { return impl.IsReadOnly; }
-		}
-
-		public virtual bool IsSynchronized
-		{
-			get { return impl.IsSynchronized; }
-		}
-
-		public virtual void Remove(object o)
-		{
-			impl.Remove(o);
-		}
-
-		public virtual void RemoveAll(IEnumerable e)
-		{
-			foreach (object o in e)
-			{
-				Remove(o);
-			}
-		}
-
-		public virtual object SyncRoot
-		{
-			get { return impl.SyncRoot; }
-		}
-	}
-}
diff --git a/crypto/src/util/collections/ISet.cs b/crypto/src/util/collections/ISet.cs
deleted file mode 100644
index 1f8edba40..000000000
--- a/crypto/src/util/collections/ISet.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using System;
-using System.Collections;
-
-namespace Org.BouncyCastle.Utilities.Collections
-{
-	public interface ISet
-		: ICollection
-	{
-		void Add(object o);
-		void AddAll(IEnumerable e);
-		void Clear();
-		bool Contains(object o);
-		bool IsEmpty { get; }
-		bool IsFixedSize { get; }
-		bool IsReadOnly { get; }
-		void Remove(object o);
-		void RemoveAll(IEnumerable e);
-	}
-}
diff --git a/crypto/src/util/collections/ReadOnlyCollection.cs b/crypto/src/util/collections/ReadOnlyCollection.cs
new file mode 100644
index 000000000..a44491d0b
--- /dev/null
+++ b/crypto/src/util/collections/ReadOnlyCollection.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+
+namespace Org.BouncyCastle.Utilities.Collections
+{
+    internal abstract class ReadOnlyCollection<T>
+        : ICollection<T>
+    {
+        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+        {
+            return GetEnumerator();
+        }
+
+        public bool IsReadOnly => true;
+
+        public void Add(T item) => throw new NotSupportedException();
+        public void Clear() => throw new NotSupportedException();
+        public bool Remove(T item) => throw new NotSupportedException();
+
+        public abstract bool Contains(T item);
+        public abstract int Count { get; }
+        public abstract void CopyTo(T[] array, int arrayIndex);
+        public abstract IEnumerator<T> GetEnumerator();
+    }
+
+    internal class ReadOnlyCollectionProxy<T>
+        : ReadOnlyCollection<T>
+    {
+        private readonly ICollection<T> m_target;
+
+        internal ReadOnlyCollectionProxy(ICollection<T> target)
+        {
+            if (target == null)
+                throw new ArgumentNullException(nameof(target));
+
+            m_target = target;
+        }
+
+        public override bool Contains(T item) => m_target.Contains(item);
+        public override int Count => m_target.Count;
+        public override void CopyTo(T[] array, int arrayIndex) => m_target.CopyTo(array, arrayIndex);
+        public override IEnumerator<T> GetEnumerator() => m_target.GetEnumerator();
+    }
+}
diff --git a/crypto/src/util/collections/ReadOnlyDictionary.cs b/crypto/src/util/collections/ReadOnlyDictionary.cs
new file mode 100644
index 000000000..f87bcc506
--- /dev/null
+++ b/crypto/src/util/collections/ReadOnlyDictionary.cs
@@ -0,0 +1,64 @@
+using System;
+using System.Collections.Generic;
+
+namespace Org.BouncyCastle.Utilities.Collections
+{
+    internal abstract class ReadOnlyDictionary<K, V>
+        : IDictionary<K, V>
+    {
+        public V this[K key]
+        {
+            get { return Lookup(key); }
+            set { throw new NotSupportedException(); }
+        }
+
+        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+        {
+            return GetEnumerator();
+        }
+
+        public bool IsReadOnly => true;
+
+        public void Add(K key, V value) => throw new NotSupportedException();
+        public void Add(KeyValuePair<K, V> item) => throw new NotSupportedException();
+        public void Clear() => throw new NotSupportedException();
+        public bool Remove(K key) => throw new NotSupportedException();
+        public bool Remove(KeyValuePair<K, V> item) => throw new NotSupportedException();
+
+        public abstract bool Contains(KeyValuePair<K, V> item);
+        public abstract bool ContainsKey(K key);
+        public abstract void CopyTo(KeyValuePair<K, V>[] array, int arrayIndex);
+        public abstract int Count { get; }
+        public abstract IEnumerator<KeyValuePair<K, V>> GetEnumerator();
+        public abstract ICollection<K> Keys { get; }
+        public abstract bool TryGetValue(K key, out V value);
+        public abstract ICollection<V> Values { get; }
+
+        protected abstract V Lookup(K key);
+    }
+
+    internal class ReadOnlyDictionaryProxy<K, V>
+        : ReadOnlyDictionary<K, V>
+    {
+        private readonly IDictionary<K, V> m_target;
+
+        internal ReadOnlyDictionaryProxy(IDictionary<K, V> target)
+        {
+            if (target == null)
+                throw new ArgumentNullException(nameof(target));
+
+            m_target = target;
+        }
+
+        public override bool Contains(KeyValuePair<K, V> item) => m_target.Contains(item);
+        public override bool ContainsKey(K key) => m_target.ContainsKey(key);
+        public override void CopyTo(KeyValuePair<K, V>[] array, int arrayIndex) => m_target.CopyTo(array, arrayIndex);
+        public override int Count => m_target.Count;
+        public override IEnumerator<KeyValuePair<K, V>> GetEnumerator() => m_target.GetEnumerator();
+        public override ICollection<K> Keys => new ReadOnlyCollectionProxy<K>(m_target.Keys);
+        public override bool TryGetValue(K key, out V value) => m_target.TryGetValue(key, out value);
+        public override ICollection<V> Values => new ReadOnlyCollectionProxy<V>(m_target.Values);
+
+        protected override V Lookup(K key) => m_target[key];
+    }
+}
diff --git a/crypto/src/util/collections/ReadOnlyList.cs b/crypto/src/util/collections/ReadOnlyList.cs
index 707c73bfd..c4d367c47 100644
--- a/crypto/src/util/collections/ReadOnlyList.cs
+++ b/crypto/src/util/collections/ReadOnlyList.cs
@@ -25,10 +25,10 @@ namespace Org.BouncyCastle.Utilities.Collections
         public bool Remove(T item) => throw new NotSupportedException();
         public void RemoveAt(int index) => throw new NotSupportedException();
 
-        public abstract int Count { get; }
 
         public abstract bool Contains(T item);
         public abstract void CopyTo(T[] array, int arrayIndex);
+        public abstract int Count { get; }
         public abstract IEnumerator<T> GetEnumerator();
         public abstract int IndexOf(T item);
 
@@ -42,6 +42,9 @@ namespace Org.BouncyCastle.Utilities.Collections
 
         internal ReadOnlyListProxy(IList<T> target)
         {
+            if (target == null)
+                throw new ArgumentNullException(nameof(target));
+
             m_target = target;
         }
 
diff --git a/crypto/src/util/collections/ReadOnlySet.cs b/crypto/src/util/collections/ReadOnlySet.cs
new file mode 100644
index 000000000..36c198f07
--- /dev/null
+++ b/crypto/src/util/collections/ReadOnlySet.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Collections.Generic;
+
+namespace Org.BouncyCastle.Utilities.Collections
+{
+    internal abstract class ReadOnlySet<T>
+        : ISet<T>
+    {
+        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+        {
+            return GetEnumerator();
+        }
+
+        public bool IsReadOnly => true;
+
+        void ICollection<T>.Add(T item) => throw new NotSupportedException();
+
+        public bool Add(T item) => throw new NotSupportedException();
+        public void Clear() => throw new NotSupportedException();
+        public void ExceptWith(IEnumerable<T> other) => throw new NotSupportedException();
+        public void IntersectWith(IEnumerable<T> other) => throw new NotSupportedException();
+        public bool Remove(T item) => throw new NotSupportedException();
+        public bool SetEquals(IEnumerable<T> other) => throw new NotSupportedException();
+        public void SymmetricExceptWith(IEnumerable<T> other) => throw new NotSupportedException();
+        public void UnionWith(IEnumerable<T> other) => throw new NotSupportedException();
+
+        public abstract bool Contains(T item);
+        public abstract void CopyTo(T[] array, int arrayIndex);
+        public abstract int Count { get; }
+        public abstract IEnumerator<T> GetEnumerator();
+        public abstract bool IsProperSubsetOf(IEnumerable<T> other);
+        public abstract bool IsProperSupersetOf(IEnumerable<T> other);
+        public abstract bool IsSubsetOf(IEnumerable<T> other);
+        public abstract bool IsSupersetOf(IEnumerable<T> other);
+        public abstract bool Overlaps(IEnumerable<T> other);
+    }
+
+    internal class ReadOnlySetProxy<T>
+        : ReadOnlySet<T>
+    {
+        private readonly ISet<T> m_target;
+
+        internal ReadOnlySetProxy(ISet<T> target)
+        {
+            if (target == null)
+                throw new ArgumentNullException(nameof(target));
+
+            m_target = target;
+        }
+
+        public override bool Contains(T item) => m_target.Contains(item);
+        public override void CopyTo(T[] array, int arrayIndex) => m_target.CopyTo(array, arrayIndex);
+        public override int Count => m_target.Count;
+        public override IEnumerator<T> GetEnumerator() => m_target.GetEnumerator();
+        public override bool IsProperSubsetOf(IEnumerable<T> other) => m_target.IsProperSubsetOf(other);
+        public override bool IsProperSupersetOf(IEnumerable<T> other) => m_target.IsProperSupersetOf(other);
+        public override bool IsSubsetOf(IEnumerable<T> other) => m_target.IsSubsetOf(other);
+        public override bool IsSupersetOf(IEnumerable<T> other) => m_target.IsSupersetOf(other);
+        public override bool Overlaps(IEnumerable<T> other) => m_target.Overlaps(other);
+    }
+}
diff --git a/crypto/src/util/collections/UnmodifiableDictionary.cs b/crypto/src/util/collections/UnmodifiableDictionary.cs
deleted file mode 100644
index 3b4ba22ae..000000000
--- a/crypto/src/util/collections/UnmodifiableDictionary.cs
+++ /dev/null
@@ -1,64 +0,0 @@
-using System;
-using System.Collections;
-
-namespace Org.BouncyCastle.Utilities.Collections
-{
-	public abstract class UnmodifiableDictionary
-		: IDictionary
-	{
-		protected UnmodifiableDictionary()
-		{
-		}
-
-		public virtual void Add(object k, object v)
-		{
-			throw new NotSupportedException();
-		}
-
-		public virtual void Clear()
-		{
-			throw new NotSupportedException();
-		}
-
-		public abstract bool Contains(object k);
-
-		public abstract void CopyTo(Array array, int index);
-
-		public abstract int Count { get; }
-
-		System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
-		{
-			return GetEnumerator();
-		}
-
-		public abstract IDictionaryEnumerator GetEnumerator();
-
-		public virtual void Remove(object k)
-		{
-			throw new NotSupportedException();
-		}
-
-		public abstract bool IsFixedSize { get; }
-
-		public virtual bool IsReadOnly
-		{
-			get { return true; }
-		}
-
-		public abstract bool IsSynchronized { get; }
-
-		public abstract object SyncRoot { get; }
-
-		public abstract ICollection Keys { get; }
-
-		public abstract ICollection Values { get; }
-
-		public virtual object this[object k]
-		{
-			get { return GetValue(k); }
-			set { throw new NotSupportedException(); }
-		}
-
-		protected abstract object GetValue(object k);
-	}
-}
diff --git a/crypto/src/util/collections/UnmodifiableDictionaryProxy.cs b/crypto/src/util/collections/UnmodifiableDictionaryProxy.cs
deleted file mode 100644
index 0fca909a3..000000000
--- a/crypto/src/util/collections/UnmodifiableDictionaryProxy.cs
+++ /dev/null
@@ -1,66 +0,0 @@
-using System;
-using System.Collections;
-
-namespace Org.BouncyCastle.Utilities.Collections
-{
-	public class UnmodifiableDictionaryProxy
-		: UnmodifiableDictionary
-	{
-		private readonly IDictionary d;
-
-		public UnmodifiableDictionaryProxy(IDictionary d)
-		{
-			this.d = d;
-		}
-
-		public override bool Contains(object k)
-		{
-			return d.Contains(k);
-		}
-
-		public override void CopyTo(Array array, int index)
-		{
-			d.CopyTo(array, index);
-		}
-
-		public override int Count
-		{
-			get { return d.Count; }
-		}
-
-		public override IDictionaryEnumerator GetEnumerator()
-		{
-			return d.GetEnumerator();
-		}
-
-		public override bool IsFixedSize
-		{
-			get { return d.IsFixedSize; }
-		}
-
-		public override bool IsSynchronized
-		{
-			get { return d.IsSynchronized; }
-		}
-
-		public override object SyncRoot
-		{
-			get { return d.SyncRoot; }
-		}
-
-		public override ICollection Keys
-		{
-			get { return d.Keys; }
-		}
-
-		public override ICollection Values
-		{
-			get { return d.Values; }
-		}
-
-		protected override object GetValue(object k)
-		{
-			return d[k];
-		}
-	}
-}
diff --git a/crypto/src/util/collections/UnmodifiableList.cs b/crypto/src/util/collections/UnmodifiableList.cs
deleted file mode 100644
index 28e49eac3..000000000
--- a/crypto/src/util/collections/UnmodifiableList.cs
+++ /dev/null
@@ -1,67 +0,0 @@
-using System;
-using System.Collections;
-
-namespace Org.BouncyCastle.Utilities.Collections
-{
-	public abstract class UnmodifiableList
-		: IList
-	{
-		protected UnmodifiableList()
-		{
-		}
-
-		public virtual int Add(object o)
-		{
-			throw new NotSupportedException();
-		}
-
-		public virtual void Clear()
-		{
-			throw new NotSupportedException();
-		}
-
-		public abstract bool Contains(object o);
-
-		public abstract void CopyTo(Array array, int index);
-
-		public abstract int Count { get; }
-
-		public abstract IEnumerator GetEnumerator();
-
-		public abstract int IndexOf(object o);
-
-		public virtual void Insert(int i, object o)
-		{
-			throw new NotSupportedException();
-		}
-
-		public abstract bool IsFixedSize { get; }
-
-		public virtual bool IsReadOnly
-		{
-			get { return true; }
-		}
-
-		public abstract bool IsSynchronized { get; }
-
-		public virtual void Remove(object o)
-		{
-			throw new NotSupportedException();
-		}
-
-		public virtual void RemoveAt(int i)
-		{
-			throw new NotSupportedException();
-		}
-
-		public abstract object SyncRoot { get; }
-		
-		public virtual object this[int i]
-		{
-			get { return GetValue(i); }
-			set { throw new NotSupportedException(); }
-		}
-
-		protected abstract object GetValue(int i);
-	}
-}
diff --git a/crypto/src/util/collections/UnmodifiableListProxy.cs b/crypto/src/util/collections/UnmodifiableListProxy.cs
deleted file mode 100644
index 9d00737ef..000000000
--- a/crypto/src/util/collections/UnmodifiableListProxy.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-using System;
-using System.Collections;
-
-namespace Org.BouncyCastle.Utilities.Collections
-{
-	public class UnmodifiableListProxy
-		: UnmodifiableList
-	{
-		private readonly IList l;
-
-		public UnmodifiableListProxy(IList l)
-		{
-			this.l = l;
-		}
-
-		public override bool Contains(object o)
-		{
-			return l.Contains(o);
-		}
-
-		public override void CopyTo(Array array, int index)
-		{
-			l.CopyTo(array, index);
-		}
-
-		public override int Count
-		{
-			get { return l.Count; }
-		}
-
-		public override IEnumerator GetEnumerator()
-		{
-			return l.GetEnumerator();
-		}
-
-		public override int IndexOf(object o)
-		{
-			return l.IndexOf(o);
-		}
-
-		public override bool IsFixedSize
-		{
-			get { return l.IsFixedSize; }
-		}
-
-		public override bool IsSynchronized
-		{
-			get { return l.IsSynchronized; }
-		}
-
-		public override object SyncRoot
-		{
-			get { return l.SyncRoot; }
-		}
-
-		protected override object GetValue(int i)
-		{
-			return l[i];
-		}
-	}
-}
diff --git a/crypto/src/util/collections/UnmodifiableSet.cs b/crypto/src/util/collections/UnmodifiableSet.cs
deleted file mode 100644
index 8792815ac..000000000
--- a/crypto/src/util/collections/UnmodifiableSet.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-using System;
-using System.Collections;
-
-namespace Org.BouncyCastle.Utilities.Collections
-{
-	public abstract class UnmodifiableSet
-		: ISet
-	{
-		protected UnmodifiableSet()
-		{
-		}
-
-		public virtual void Add(object o)
-		{
-			throw new NotSupportedException();
-		}
-
-		public virtual void AddAll(IEnumerable e)
-		{
-			throw new NotSupportedException();
-		}
-
-		public virtual void Clear()
-		{
-			throw new NotSupportedException();
-		}
-		
-		public abstract bool Contains(object o);
-
-		public abstract void CopyTo(Array array, int index);
-
-		public abstract int Count { get; }
-
-		public abstract IEnumerator GetEnumerator();
-
-		public abstract bool IsEmpty { get; }
-
-		public abstract bool IsFixedSize { get; }
-
-		public virtual bool IsReadOnly
-		{
-			get { return true; }
-		}
-
-		public abstract bool IsSynchronized { get; }
-
-		public abstract object SyncRoot { get; }
-
-		public virtual void Remove(object o)
-		{
-			throw new NotSupportedException();
-		}
-
-		public virtual void RemoveAll(IEnumerable e)
-		{
-			throw new NotSupportedException();
-		}
-	}
-}
diff --git a/crypto/src/util/collections/UnmodifiableSetProxy.cs b/crypto/src/util/collections/UnmodifiableSetProxy.cs
deleted file mode 100644
index e119e2957..000000000
--- a/crypto/src/util/collections/UnmodifiableSetProxy.cs
+++ /dev/null
@@ -1,56 +0,0 @@
-using System;
-using System.Collections;
-
-namespace Org.BouncyCastle.Utilities.Collections
-{
-	public class UnmodifiableSetProxy
-		: UnmodifiableSet
-	{
-		private readonly ISet s;
-
-		public UnmodifiableSetProxy (ISet s)
-		{
-			this.s = s;
-		}
-
-		public override bool Contains(object o)
-		{
-			return s.Contains(o);
-		}
-
-		public override void CopyTo(Array array, int index)
-		{
-			s.CopyTo(array, index);
-		}
-
-		public override int Count
-		{
-			get { return s.Count; }
-		}
-
-		public override IEnumerator GetEnumerator()
-		{
-			return s.GetEnumerator();
-		}
-
-		public override bool IsEmpty
-		{
-			get { return s.IsEmpty; }
-		}
-
-		public override bool IsFixedSize
-		{
-			get { return s.IsFixedSize; }
-		}
-
-		public override bool IsSynchronized
-		{
-			get { return s.IsSynchronized; }
-		}
-
-		public override object SyncRoot
-		{
-			get { return s.SyncRoot; }
-		}
-	}
-}
diff --git a/crypto/src/util/io/pem/PemObject.cs b/crypto/src/util/io/pem/PemObject.cs
index fce429f39..2a152f81d 100644
--- a/crypto/src/util/io/pem/PemObject.cs
+++ b/crypto/src/util/io/pem/PemObject.cs
@@ -1,26 +1,24 @@
 using System;
-using System.Collections;
-
-using Org.BouncyCastle.Utilities.Collections;
+using System.Collections.Generic;
 
 namespace Org.BouncyCastle.Utilities.IO.Pem
 {
 	public class PemObject
 		: PemObjectGenerator
 	{
-		private string		type;
-		private IList		headers;
-		private byte[]		content;
+		private string type;
+		private IList<PemHeader> headers;
+		private byte[] content;
 
 		public PemObject(string type, byte[] content)
-			: this(type, Platform.CreateArrayList(), content)
+			: this(type, new List<PemHeader>(), content)
 		{
 		}
 
-		public PemObject(string type, IList headers, byte[] content)
+		public PemObject(string type, IList<PemHeader> headers, byte[] content)
 		{
 			this.type = type;
-            this.headers = Platform.CreateArrayList(headers);
+            this.headers = new List<PemHeader>(headers);
 			this.content = content;
 		}
 
@@ -29,7 +27,7 @@ namespace Org.BouncyCastle.Utilities.IO.Pem
 			get { return type; }
 		}
 
-		public IList Headers
+		public IList<PemHeader> Headers
 		{
 			get { return headers; }
 		}
diff --git a/crypto/src/util/io/pem/PemReader.cs b/crypto/src/util/io/pem/PemReader.cs
index a32ca8181..cd19e95b8 100644
--- a/crypto/src/util/io/pem/PemReader.cs
+++ b/crypto/src/util/io/pem/PemReader.cs
@@ -1,8 +1,7 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
-
 using Org.BouncyCastle.Utilities.Encoders;
 
 namespace Org.BouncyCastle.Utilities.IO.Pem
@@ -13,11 +12,9 @@ namespace Org.BouncyCastle.Utilities.IO.Pem
 		private readonly TextReader reader;
 		private readonly MemoryStream buffer;
 		private readonly StreamWriter textBuffer;
-		private readonly IList pushback = Platform.CreateArrayList();
+		private readonly List<int> pushback = new List<int>();
 		int c = 0;
 
-		
-
 		public PemReader(TextReader reader)
 		{
 			if (reader == null)
@@ -47,7 +44,7 @@ namespace Org.BouncyCastle.Utilities.IO.Pem
 			// Look for BEGIN
 			//
 
-			for (; ; )
+			for (;;)
 			{
 
 				// Seek a leading dash, ignore anything up to that point.
@@ -107,7 +104,7 @@ namespace Org.BouncyCastle.Utilities.IO.Pem
 			// Look for a colon for up to 64 characters, as an indication there might be a header.
 			//
 
-			IList headers = Platform.CreateArrayList();
+			var headers = new List<PemHeader>();
 
 			while (seekColon(64))
             {
@@ -227,7 +224,7 @@ namespace Org.BouncyCastle.Utilities.IO.Pem
 		{
 			c = 0;
 			bool colonFound = false;
-			IList read = Platform.CreateArrayList();
+			var read = new List<int>();
 
 			for (; upTo>=0 && c >=0; upTo--)
             {
@@ -308,7 +305,6 @@ namespace Org.BouncyCastle.Utilities.IO.Pem
 
 			return true;
         }
-		
 
 		/// <summary>
 		/// Consume until dash.
@@ -338,8 +334,6 @@ namespace Org.BouncyCastle.Utilities.IO.Pem
 			return c > -1;
 		}
 
-
-
 		private void PushBack(int value)
         {
 			if (pushback.Count == 0)
@@ -351,21 +345,16 @@ namespace Org.BouncyCastle.Utilities.IO.Pem
             }
         }
 
-
 		private int Read()
         {
-			if (pushback.Count>0)
+			if (pushback.Count > 0)
             {
-				int i = (int)pushback[0];
+				int i = pushback[0];
 				pushback.RemoveAt(0);
 				return i;
             }
 
 			return reader.Read();
         }
-
-
-
-
 	}
 }
diff --git a/crypto/src/util/io/pem/PemWriter.cs b/crypto/src/util/io/pem/PemWriter.cs
index e85b31543..87968a727 100644
--- a/crypto/src/util/io/pem/PemWriter.cs
+++ b/crypto/src/util/io/pem/PemWriter.cs
@@ -1,5 +1,4 @@
 using System;
-using System.Collections;
 using System.IO;
 
 using Org.BouncyCastle.Utilities.Encoders;
diff --git a/crypto/src/x509/SubjectPublicKeyInfoFactory.cs b/crypto/src/x509/SubjectPublicKeyInfoFactory.cs
index d085601e3..b80e298ce 100644
--- a/crypto/src/x509/SubjectPublicKeyInfoFactory.cs
+++ b/crypto/src/x509/SubjectPublicKeyInfoFactory.cs
@@ -143,7 +143,7 @@ namespace Org.BouncyCastle.X509
                 if (_key.AlgorithmName == "ECGOST3410")
                 {
                     if (_key.PublicKeyParamSet == null)
-                        throw Platform.CreateNotImplementedException("Not a CryptoPro parameter set");
+                        throw new NotImplementedException("Not a CryptoPro parameter set");
 
                     ECPoint q = _key.Q.Normalize();
                     BigInteger bX = q.AffineXCoord.ToBigInteger();
@@ -192,7 +192,7 @@ namespace Org.BouncyCastle.X509
                 Gost3410PublicKeyParameters _key = (Gost3410PublicKeyParameters) publicKey;
 
                 if (_key.PublicKeyParamSet == null)
-                    throw Platform.CreateNotImplementedException("Not a CryptoPro parameter set");
+                    throw new NotImplementedException("Not a CryptoPro parameter set");
 
                 byte[] keyEnc = _key.Y.ToByteArrayUnsigned();
                 byte[] keyBytes = new byte[keyEnc.Length];
diff --git a/crypto/src/x509/X509CertPairParser.cs b/crypto/src/x509/X509CertPairParser.cs
index 89a8a8e96..26b417898 100644
--- a/crypto/src/x509/X509CertPairParser.cs
+++ b/crypto/src/x509/X509CertPairParser.cs
@@ -1,11 +1,10 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.X509;
 using Org.BouncyCastle.Security.Certificates;
-using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.IO;
 
 namespace Org.BouncyCastle.X509
@@ -27,8 +26,7 @@ namespace Org.BouncyCastle.X509
 		/// Create loading data from byte array.
 		/// </summary>
 		/// <param name="input"></param>
-		public X509CertificatePair ReadCertPair(
-			byte[] input)
+		public X509CertificatePair ReadCertPair(byte[] input)
 		{
 			return ReadCertPair(new MemoryStream(input, false));
 		}
@@ -37,14 +35,12 @@ namespace Org.BouncyCastle.X509
 		/// Create loading data from byte array.
 		/// </summary>
 		/// <param name="input"></param>
-		public ICollection ReadCertPairs(
-			byte[] input)
+		public IList<X509CertificatePair> ReadCertPairs(byte[] input)
 		{
 			return ReadCertPairs(new MemoryStream(input, false));
 		}
 
-		public X509CertificatePair ReadCertPair(
-			Stream inStream)
+		public X509CertificatePair ReadCertPair(Stream inStream)
 		{
 			if (inStream == null)
 				throw new ArgumentNullException("inStream");
@@ -85,12 +81,11 @@ namespace Org.BouncyCastle.X509
 			}
 		}
 
-		public ICollection ReadCertPairs(
-			Stream inStream)
+		public IList<X509CertificatePair> ReadCertPairs(Stream inStream)
 		{
-			X509CertificatePair certPair;
-			IList certPairs = Platform.CreateArrayList();
+			var certPairs = new List<X509CertificatePair>();
 
+			X509CertificatePair certPair;
 			while ((certPair = ReadCertPair(inStream)) != null)
 			{
 				certPairs.Add(certPair);
diff --git a/crypto/src/x509/X509Certificate.cs b/crypto/src/x509/X509Certificate.cs
index cc390f360..275b3f19e 100644
--- a/crypto/src/x509/X509Certificate.cs
+++ b/crypto/src/x509/X509Certificate.cs
@@ -56,8 +56,8 @@ namespace Org.BouncyCastle.X509
         }
 
         private readonly X509CertificateStructure c;
-        //private Hashtable pkcs12Attributes = Platform.CreateHashtable();
-        //private ArrayList pkcs12Ordering = Platform.CreateArrayList();
+        //private Dictionary<> pkcs12Attributes = new Dictionary<>();
+        //private List<> pkcs12Ordering = new List<>();
         private readonly string sigAlgName;
         private readonly byte[] sigAlgParams;
         private readonly BasicConstraints basicConstraints;
diff --git a/crypto/src/x509/X509Crl.cs b/crypto/src/x509/X509Crl.cs
index 9acebf2dd..921e9881b 100644
--- a/crypto/src/x509/X509Crl.cs
+++ b/crypto/src/x509/X509Crl.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 using System.Text;
 
@@ -12,7 +12,6 @@ using Org.BouncyCastle.Math;
 using Org.BouncyCastle.Security;
 using Org.BouncyCastle.Security.Certificates;
 using Org.BouncyCastle.Utilities;
-using Org.BouncyCastle.Utilities.Collections;
 using Org.BouncyCastle.Utilities.Date;
 using Org.BouncyCastle.Utilities.Encoders;
 using Org.BouncyCastle.X509.Extension;
@@ -174,13 +173,13 @@ namespace Org.BouncyCastle.X509
 			}
 		}
 
-		private ISet LoadCrlEntries()
+		private ISet<X509CrlEntry> LoadCrlEntries()
 		{
-			ISet entrySet = new HashSet();
-			IEnumerable certs = c.GetRevokedCertificateEnumeration();
+			var entrySet = new HashSet<X509CrlEntry>();
+			var revoked = c.GetRevokedCertificateEnumeration();
 
 			X509Name previousCertificateIssuer = IssuerDN;
-			foreach (CrlEntry entry in certs)
+			foreach (CrlEntry entry in revoked)
 			{
 				X509CrlEntry crlEntry = new X509CrlEntry(entry, isIndirect, previousCertificateIssuer);
 				entrySet.Add(crlEntry);
@@ -193,7 +192,7 @@ namespace Org.BouncyCastle.X509
 		public virtual X509CrlEntry GetRevokedCertificate(
 			BigInteger serialNumber)
 		{
-			IEnumerable certs = c.GetRevokedCertificateEnumeration();
+			var certs = c.GetRevokedCertificateEnumeration();
 
 			X509Name previousCertificateIssuer = IssuerDN;
 			foreach (CrlEntry entry in certs)
@@ -211,14 +210,12 @@ namespace Org.BouncyCastle.X509
 			return null;
 		}
 
-		public virtual ISet GetRevokedCertificates()
+		public virtual ISet<X509CrlEntry> GetRevokedCertificates()
 		{
-			ISet entrySet = LoadCrlEntries();
+			var entrySet = LoadCrlEntries();
 
 			if (entrySet.Count > 0)
-			{
-				return entrySet; // TODO? Collections.unmodifiableSet(entrySet);
-			}
+				return entrySet;
 
 			return null;
 		}
@@ -339,7 +336,7 @@ namespace Org.BouncyCastle.X509
 
 			if (extensions != null)
 			{
-				IEnumerator e = extensions.ExtensionOids.GetEnumerator();
+				var e = extensions.ExtensionOids.GetEnumerator();
 
 				if (e.MoveNext())
 				{
@@ -348,7 +345,7 @@ namespace Org.BouncyCastle.X509
 
 				do
 				{
-					DerObjectIdentifier oid = (DerObjectIdentifier) e.Current;
+					DerObjectIdentifier oid = e.Current;
 					X509Extension ext = extensions.GetExtension(oid);
 
 					if (ext.Value != null)
@@ -404,7 +401,7 @@ namespace Org.BouncyCastle.X509
 				while (e.MoveNext());
 			}
 
-			ISet certSet = GetRevokedCertificates();
+			var certSet = GetRevokedCertificates();
 			if (certSet != null)
 			{
 				foreach (X509CrlEntry entry in certSet)
diff --git a/crypto/src/x509/X509CrlEntry.cs b/crypto/src/x509/X509CrlEntry.cs
index 9660a7099..30e0da2db 100644
--- a/crypto/src/x509/X509CrlEntry.cs
+++ b/crypto/src/x509/X509CrlEntry.cs
@@ -1,5 +1,4 @@
 using System;
-using System.Collections;
 using System.Text;
 
 using Org.BouncyCastle.Asn1;
@@ -176,14 +175,14 @@ namespace Org.BouncyCastle.X509
 
 			if (extensions != null)
 			{
-				IEnumerator e = extensions.ExtensionOids.GetEnumerator();
+				var e = extensions.ExtensionOids.GetEnumerator();
 				if (e.MoveNext())
 				{
 					buf.Append("   crlEntryExtensions:").Append(nl);
 
 					do
 					{
-						DerObjectIdentifier oid = (DerObjectIdentifier)e.Current;
+						DerObjectIdentifier oid = e.Current;
 						X509Extension ext = extensions.GetExtension(oid);
 
 						if (ext.Value != null)
diff --git a/crypto/src/x509/X509V1CertificateGenerator.cs b/crypto/src/x509/X509V1CertificateGenerator.cs
index 99543778b..aae263450 100644
--- a/crypto/src/x509/X509V1CertificateGenerator.cs
+++ b/crypto/src/x509/X509V1CertificateGenerator.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.X509;
@@ -144,7 +144,7 @@ namespace Org.BouncyCastle.X509
 		/// <summary>
 		/// Allows enumeration of the signature names supported by the generator.
 		/// </summary>
-		public IEnumerable SignatureAlgNames
+		public IEnumerable<string> SignatureAlgNames
 		{
 			get { return X509Utilities.GetAlgNames(); }
 		}
diff --git a/crypto/src/x509/X509V2AttributeCertificate.cs b/crypto/src/x509/X509V2AttributeCertificate.cs
index 61bb8c879..8c6ff0062 100644
--- a/crypto/src/x509/X509V2AttributeCertificate.cs
+++ b/crypto/src/x509/X509V2AttributeCertificate.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 using Org.BouncyCastle.Asn1;
@@ -235,7 +235,7 @@ namespace Org.BouncyCastle.X509
 			string oid)
 		{
 			Asn1Sequence seq = cert.ACInfo.Attributes;
-			IList list = Platform.CreateArrayList();
+			var list = new List<X509Attribute>();
 
 			for (int i = 0; i != seq.Count; i++)
 			{
@@ -251,16 +251,10 @@ namespace Org.BouncyCastle.X509
 				return null;
 			}
 
-            X509Attribute[] result = new X509Attribute[list.Count];
-            for (int i = 0; i < list.Count; ++i)
-            {
-                result[i] = (X509Attribute)list[i];
-            }
-            return result;
+			return list.ToArray();
 		}
 
-		public override bool Equals(
-			object obj)
+		public override bool Equals(object obj)
 		{
 			if (obj == this)
 				return true;
diff --git a/crypto/src/x509/X509V2AttributeCertificateGenerator.cs b/crypto/src/x509/X509V2AttributeCertificateGenerator.cs
index 2baf10c63..2e5c9c863 100644
--- a/crypto/src/x509/X509V2AttributeCertificateGenerator.cs
+++ b/crypto/src/x509/X509V2AttributeCertificateGenerator.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.X509;
@@ -74,7 +74,7 @@ namespace Org.BouncyCastle.X509
 		{
 			// TODO convert bool array to bit string
 			//acInfoGen.SetIssuerUniqueID(iui);
-			throw Platform.CreateNotImplementedException("SetIssuerUniqueId()");
+			throw new NotImplementedException("SetIssuerUniqueId()");
 		}
 
 		/// <summary>Add a given extension field for the standard extensions tag.</summary>
@@ -142,7 +142,7 @@ namespace Org.BouncyCastle.X509
 		/// <summary>
 		/// Allows enumeration of the signature names supported by the generator.
 		/// </summary>
-		public IEnumerable SignatureAlgNames
+		public IEnumerable<string> SignatureAlgNames
 		{
 			get { return X509Utilities.GetAlgNames(); }
 		}
diff --git a/crypto/src/x509/X509V2CRLGenerator.cs b/crypto/src/x509/X509V2CRLGenerator.cs
index ba5c7de2d..cb316f21b 100644
--- a/crypto/src/x509/X509V2CRLGenerator.cs
+++ b/crypto/src/x509/X509V2CRLGenerator.cs
@@ -1,16 +1,13 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.X509;
 using Org.BouncyCastle.Crypto;
-using Org.BouncyCastle.Crypto.Operators;
 using Org.BouncyCastle.Math;
-using Org.BouncyCastle.Security;
 using Org.BouncyCastle.Security.Certificates;
 using Org.BouncyCastle.Utilities;
-using Org.BouncyCastle.Utilities.Collections;
 
 namespace Org.BouncyCastle.X509
 {
@@ -101,13 +98,12 @@ namespace Org.BouncyCastle.X509
 		*
 		* @param other the X509Crl to source the other entries from.
 		*/
-		public void AddCrl(
-			X509Crl other)
+		public void AddCrl(X509Crl other)
 		{
 			if (other == null)
 				throw new ArgumentNullException("other");
 
-			ISet revocations = other.GetRevokedCertificates();
+			var revocations = other.GetRevokedCertificates();
 
 			if (revocations != null)
 			{
@@ -216,7 +212,7 @@ namespace Org.BouncyCastle.X509
 		/// <summary>
 		/// Allows enumeration of the signature names supported by the generator.
 		/// </summary>
-		public IEnumerable SignatureAlgNames
+		public IEnumerable<string> SignatureAlgNames
 		{
 			get { return X509Utilities.GetAlgNames(); }
 		}
diff --git a/crypto/src/x509/extension/X509ExtensionUtil.cs b/crypto/src/x509/extension/X509ExtensionUtil.cs
index 5f65ebfda..b751658e1 100644
--- a/crypto/src/x509/extension/X509ExtensionUtil.cs
+++ b/crypto/src/x509/extension/X509ExtensionUtil.cs
@@ -1,11 +1,10 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.X509;
 using Org.BouncyCastle.Security.Certificates;
-using Org.BouncyCastle.Utilities;
 
 namespace Org.BouncyCastle.X509.Extension
 {
@@ -17,66 +16,64 @@ namespace Org.BouncyCastle.X509.Extension
 			return Asn1Object.FromByteArray(extensionValue.GetOctets());
 		}
 
-		public static ICollection GetIssuerAlternativeNames(
-			X509Certificate cert)
+		public static IList<IList<object>> GetIssuerAlternativeNames(X509Certificate cert)
 		{
 			Asn1OctetString extVal = cert.GetExtensionValue(X509Extensions.IssuerAlternativeName);
 
 			return GetAlternativeName(extVal);
 		}
 
-		public static ICollection GetSubjectAlternativeNames(
-			X509Certificate cert)
+		public static IList<IList<object>> GetSubjectAlternativeNames(X509Certificate cert)
 		{
 			Asn1OctetString extVal = cert.GetExtensionValue(X509Extensions.SubjectAlternativeName);
 
 			return GetAlternativeName(extVal);
 		}
 
-		private static ICollection GetAlternativeName(
+		private static IList<IList<object>> GetAlternativeName(
 			Asn1OctetString extVal)
 		{
-			IList temp = Platform.CreateArrayList();
+			var result = new List<IList<object>>();
 
 			if (extVal != null)
 			{
 				try
 				{
-					Asn1Sequence seq = DerSequence.GetInstance(FromExtensionValue(extVal));
+					Asn1Sequence seq = Asn1Sequence.GetInstance(FromExtensionValue(extVal));
 
 					foreach (Asn1Encodable primName in seq)
 					{
-                        IList list = Platform.CreateArrayList();
-                        GeneralName genName = GeneralName.GetInstance(primName);
+						GeneralName genName = GeneralName.GetInstance(primName);
 
+						var list = new List<object>(2);
 						list.Add(genName.TagNo);
 
 						switch (genName.TagNo)
 						{
-							case GeneralName.EdiPartyName:
-							case GeneralName.X400Address:
-							case GeneralName.OtherName:
-								list.Add(genName.Name.ToAsn1Object());
-								break;
-							case GeneralName.DirectoryName:
-								list.Add(X509Name.GetInstance(genName.Name).ToString());
-								break;
-							case GeneralName.DnsName:
-							case GeneralName.Rfc822Name:
-							case GeneralName.UniformResourceIdentifier:
-								list.Add(((IAsn1String)genName.Name).GetString());
-								break;
-							case GeneralName.RegisteredID:
-								list.Add(DerObjectIdentifier.GetInstance(genName.Name).Id);
-								break;
-							case GeneralName.IPAddress:
-								list.Add(DerOctetString.GetInstance(genName.Name).GetOctets());
-								break;
-							default:
-								throw new IOException("Bad tag number: " + genName.TagNo);
+						case GeneralName.EdiPartyName:
+						case GeneralName.X400Address:
+						case GeneralName.OtherName:
+							list.Add(genName.Name.ToAsn1Object());
+							break;
+						case GeneralName.DirectoryName:
+							list.Add(X509Name.GetInstance(genName.Name).ToString());
+							break;
+						case GeneralName.DnsName:
+						case GeneralName.Rfc822Name:
+						case GeneralName.UniformResourceIdentifier:
+							list.Add(((IAsn1String)genName.Name).GetString());
+							break;
+						case GeneralName.RegisteredID:
+							list.Add(DerObjectIdentifier.GetInstance(genName.Name).Id);
+							break;
+						case GeneralName.IPAddress:
+							list.Add(Asn1OctetString.GetInstance(genName.Name).GetOctets());
+							break;
+						default:
+							throw new IOException("Bad tag number: " + genName.TagNo);
 						}
 
-						temp.Add(list);
+						result.Add(list);
 					}
 				}
 				catch (Exception e)
@@ -85,7 +82,7 @@ namespace Org.BouncyCastle.X509.Extension
 				}
 			}
 
-			return temp;
+			return result;
 		}
 	}
 }
diff --git a/crypto/src/x509/store/X509AttrCertStoreSelector.cs b/crypto/src/x509/store/X509AttrCertStoreSelector.cs
index b25d0de19..5744289e9 100644
--- a/crypto/src/x509/store/X509AttrCertStoreSelector.cs
+++ b/crypto/src/x509/store/X509AttrCertStoreSelector.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.X509;
@@ -27,8 +27,8 @@ namespace Org.BouncyCastle.X509.Store
 		private AttributeCertificateHolder holder;
 		private AttributeCertificateIssuer issuer;
 		private BigInteger serialNumber;
-		private ISet targetNames = new HashSet();
-		private ISet targetGroups = new HashSet();
+		private ISet<GeneralName> targetNames = new HashSet<GeneralName>();
+		private ISet<GeneralName> targetGroups = new HashSet<GeneralName>();
 
 		public X509AttrCertStoreSelector()
 		{
@@ -42,8 +42,8 @@ namespace Org.BouncyCastle.X509.Store
 			this.holder = o.holder;
 			this.issuer = o.issuer;
 			this.serialNumber = o.serialNumber;
-			this.targetGroups = new HashSet(o.targetGroups);
-			this.targetNames = new HashSet(o.targetNames);
+			this.targetGroups = new HashSet<GeneralName>(o.targetGroups);
+			this.targetNames = new HashSet<GeneralName>(o.targetNames);
 		}
 
 		/// <summary>
@@ -225,8 +225,7 @@ namespace Org.BouncyCastle.X509.Store
 		* @param name a byte array containing the name in ASN.1 DER encoded form of a GeneralName
 		* @throws IOException if a parsing error occurs.
 		*/
-		public void AddTargetName(
-			byte[] name)
+		public void AddTargetName(byte[] name)
 		{
 			AddTargetName(GeneralName.GetInstance(Asn1Object.FromByteArray(name)));
 		}
@@ -244,8 +243,7 @@ namespace Org.BouncyCastle.X509.Store
 		* @see #AddTargetName(byte[])
 		* @see #AddTargetName(GeneralName)
 		*/
-		public void SetTargetNames(
-			IEnumerable names)
+		public void SetTargetNames(IEnumerable<object> names)
 		{
 			targetNames = ExtractGeneralNames(names);
 		}
@@ -259,9 +257,9 @@ namespace Org.BouncyCastle.X509.Store
 		* @return The collection of target names
 		* @see #setTargetNames(Collection)
 		*/
-		public IEnumerable GetTargetNames()
+		public IEnumerable<GeneralName> GetTargetNames()
 		{
-			return new EnumerableProxy(targetNames);
+			return CollectionUtilities.Proxy(targetNames);
 		}
 
 		/**
@@ -277,8 +275,7 @@ namespace Org.BouncyCastle.X509.Store
 		*
 		* @param group The group as GeneralName form (not <code>null</code>)
 		*/
-		public void AddTargetGroup(
-			GeneralName group)
+		public void AddTargetGroup(GeneralName group)
 		{
 			targetGroups.Add(group);
 		}
@@ -297,8 +294,7 @@ namespace Org.BouncyCastle.X509.Store
 		* @param name a byte array containing the group in ASN.1 DER encoded form of a GeneralName
 		* @throws IOException if a parsing error occurs.
 		*/
-		public void AddTargetGroup(
-			byte[] name)
+		public void AddTargetGroup(byte[] name)
 		{
 			AddTargetGroup(GeneralName.GetInstance(Asn1Object.FromByteArray(name)));
 		}
@@ -316,8 +312,7 @@ namespace Org.BouncyCastle.X509.Store
 		* @see #AddTargetGroup(byte[])
 		* @see #AddTargetGroup(GeneralName)
 		*/
-		public void SetTargetGroups(
-			IEnumerable names)
+		public void SetTargetGroups(IEnumerable<object> names)
 		{
 			targetGroups = ExtractGeneralNames(names);
 		}
@@ -331,28 +326,31 @@ namespace Org.BouncyCastle.X509.Store
 		* @return The collection of target groups.
 		* @see #setTargetGroups(Collection)
 		*/
-		public IEnumerable GetTargetGroups()
+		public IEnumerable<GeneralName> GetTargetGroups()
 		{
-			return new EnumerableProxy(targetGroups);
+			return CollectionUtilities.Proxy(targetGroups);
 		}
 
-		private ISet ExtractGeneralNames(
-			IEnumerable names)
+		private ISet<GeneralName> ExtractGeneralNames(IEnumerable<object> names)
 		{
-			ISet result = new HashSet();
+			var result = new HashSet<GeneralName>();
 
 			if (names != null)
 			{
 				foreach (object o in names)
 				{
-					if (o is GeneralName)
+					if (o is GeneralName gn)
 					{
-						result.Add(o);
+						result.Add(gn);
 					}
-					else
+					else if (o is byte[] bs)
 					{
-						result.Add(GeneralName.GetInstance(Asn1Object.FromByteArray((byte[]) o)));
+						result.Add(GeneralName.GetInstance(Asn1Object.FromByteArray(bs)));
 					}
+					else
+                    {
+						throw new InvalidOperationException();
+                    }
 				}
 			}
 
diff --git a/crypto/src/x509/store/X509CertStoreSelector.cs b/crypto/src/x509/store/X509CertStoreSelector.cs
index 197e8f26d..71b5419a7 100644
--- a/crypto/src/x509/store/X509CertStoreSelector.cs
+++ b/crypto/src/x509/store/X509CertStoreSelector.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.X509;
@@ -20,11 +20,11 @@ namespace Org.BouncyCastle.X509.Store
 		private int basicConstraints = -1;
 		private X509Certificate certificate;
 		private DateTimeObject certificateValid;
-		private ISet extendedKeyUsage;
+		private ISet<DerObjectIdentifier> extendedKeyUsage;
         private bool ignoreX509NameOrdering;
 		private X509Name issuer;
 		private bool[] keyUsage;
-		private ISet policy;
+		private ISet<DerObjectIdentifier> policy;
 		private DateTimeObject privateKeyValid;
 		private BigInteger serialNumber;
 		private X509Name subject;
@@ -91,7 +91,7 @@ namespace Org.BouncyCastle.X509.Store
 			set { certificateValid = value; }
 		}
 
-		public ISet ExtendedKeyUsage
+		public ISet<DerObjectIdentifier> ExtendedKeyUsage
 		{
 			get { return CopySet(extendedKeyUsage); }
 			set { extendedKeyUsage = CopySet(value); }
@@ -118,7 +118,7 @@ namespace Org.BouncyCastle.X509.Store
 		/// <summary>
 		/// An <code>ISet</code> of <code>DerObjectIdentifier</code> objects.
 		/// </summary>
-		public ISet Policy
+		public ISet<DerObjectIdentifier> Policy
 		{
 			get { return CopySet(policy); }
 			set { policy = CopySet(value); }
@@ -300,10 +300,9 @@ namespace Org.BouncyCastle.X509.Store
 			return b == null ? null : (bool[]) b.Clone();
 		}
 
-		private static ISet CopySet(
-			ISet s)
+		private static ISet<T> CopySet<T>(ISet<T> s)
 		{
-			return s == null ? null : new HashSet(s);
+			return s == null ? null : new HashSet<T>(s);
 		}
 
 		private static SubjectPublicKeyInfo GetSubjectPublicKey(
diff --git a/crypto/src/x509/store/X509CrlStoreSelector.cs b/crypto/src/x509/store/X509CrlStoreSelector.cs
index dcf8f8876..365ec1d38 100644
--- a/crypto/src/x509/store/X509CrlStoreSelector.cs
+++ b/crypto/src/x509/store/X509CrlStoreSelector.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.X509;
@@ -18,7 +18,7 @@ namespace Org.BouncyCastle.X509.Store
 
 		private X509Certificate certificateChecking;
 		private DateTimeObject dateAndTime;
-		private ICollection issuers;
+		private IList<X509Name> issuers;
 		private BigInteger maxCrlNumber;
 		private BigInteger minCrlNumber;
 
@@ -70,10 +70,10 @@ namespace Org.BouncyCastle.X509.Store
 		/// <summary>
 		/// An <code>ICollection</code> of <code>X509Name</code> objects
 		/// </summary>
-		public ICollection Issuers
+		public IList<X509Name> Issuers
 		{
-			get { return Platform.CreateArrayList(issuers); }
-            set { issuers = Platform.CreateArrayList(value); }
+			get { return new List<X509Name>(issuers); }
+            set { issuers = new List<X509Name>(value); }
 		}
 
 		public BigInteger MaxCrlNumber
diff --git a/crypto/test/src/asn1/test/AttributeTableUnitTest.cs b/crypto/test/src/asn1/test/AttributeTableUnitTest.cs
index c6d69fa2b..d5f49f0a8 100644
--- a/crypto/test/src/asn1/test/AttributeTableUnitTest.cs
+++ b/crypto/test/src/asn1/test/AttributeTableUnitTest.cs
@@ -1,9 +1,7 @@
 using System;
-using System.Collections;
 
 using NUnit.Framework;
 
-using Org.BouncyCastle.Asn1;
 using Asn1Cms = Org.BouncyCastle.Asn1.Cms;
 using Org.BouncyCastle.Utilities.Test;
 
diff --git a/crypto/test/src/asn1/test/X509NameTest.cs b/crypto/test/src/asn1/test/X509NameTest.cs
index c344042a2..bafec3226 100644
--- a/crypto/test/src/asn1/test/X509NameTest.cs
+++ b/crypto/test/src/asn1/test/X509NameTest.cs
@@ -1,5 +1,4 @@
 using System;
-using System.Collections;
 using System.Collections.Generic;
 
 using NUnit.Framework;
diff --git a/crypto/test/src/cmp/test/ProtectedMessageTest.cs b/crypto/test/src/cmp/test/ProtectedMessageTest.cs
index 98bae77ee..4c242d48a 100644
--- a/crypto/test/src/cmp/test/ProtectedMessageTest.cs
+++ b/crypto/test/src/cmp/test/ProtectedMessageTest.cs
@@ -1,5 +1,4 @@
 using System;
-using System.Collections;
 using System.Collections.Generic;
 
 using NUnit.Framework;
@@ -324,7 +323,7 @@ namespace Org.BouncyCastle.Cmp.Tests
     {
         IDictionary<DerObjectIdentifier, string> attrs = new Dictionary<DerObjectIdentifier, string>();
         IList<DerObjectIdentifier> ord = new List<DerObjectIdentifier>();
-        IList values = new ArrayList();
+        IList<string> values = new List<string>();
 
         private DateTime notBefore, notAfter;
         private AsymmetricKeyParameter publicKey;
diff --git a/crypto/test/src/cms/test/CMSTestUtil.cs b/crypto/test/src/cms/test/CMSTestUtil.cs
index b6818bb8a..016260625 100644
--- a/crypto/test/src/cms/test/CMSTestUtil.cs
+++ b/crypto/test/src/cms/test/CMSTestUtil.cs
@@ -213,7 +213,7 @@ namespace Org.BouncyCastle.Cms.Tests
 				{
 					buf.Append(Encoding.ASCII.GetString(data, i, data.Length - i));
 				}
-				buf.Append('\n');
+				buf.AppendLine();
 			}
 
 			return buf.ToString();
diff --git a/crypto/test/src/crmf/test/CrmfTest.cs b/crypto/test/src/crmf/test/CrmfTest.cs
index 7a5349db1..f900e0879 100644
--- a/crypto/test/src/crmf/test/CrmfTest.cs
+++ b/crypto/test/src/crmf/test/CrmfTest.cs
@@ -1,10 +1,7 @@
 using System;
-using System.Collections;
 
 using NUnit.Framework;
 
-using Org.BouncyCastle.Asn1;
-using Org.BouncyCastle.Asn1.Cms;
 using Org.BouncyCastle.Asn1.Crmf;
 using Org.BouncyCastle.Asn1.Nist;
 using Org.BouncyCastle.Asn1.Pkcs;
@@ -156,7 +153,7 @@ namespace Org.BouncyCastle.Crmf.Tests
             IsTrue(archiveControl.EnvelopedData);
             RecipientInformationStore recips = archiveControl.GetEnvelopedData().GetRecipientInfos();
 
-            IList collection =  (IList)recips.GetRecipients();
+            var collection = recips.GetRecipients();
 
             IsTrue(collection.Count == 1);
             KeyTransRecipientInformation info = (KeyTransRecipientInformation)collection[0];
diff --git a/crypto/test/src/crypto/prng/test/DrbgTestVector.cs b/crypto/test/src/crypto/prng/test/DrbgTestVector.cs
index b3f17e458..ca64dfa5b 100644
--- a/crypto/test/src/crypto/prng/test/DrbgTestVector.cs
+++ b/crypto/test/src/crypto/prng/test/DrbgTestVector.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Utilities.Encoders;
 
@@ -16,7 +16,7 @@ namespace Org.BouncyCastle.Crypto.Prng.Test
         private string _personalisation;
         private int _ss;
         private string[] _ev;
-        private IList _ai = new ArrayList();
+        private IList<string> _ai = new List<string>();
 
         public DrbgTestVector(IDigest digest, IEntropySource eSource, bool predictionResistance, string nonce,
             int securityStrength, string[] expected)
diff --git a/crypto/test/src/crypto/test/GOST3411_2012_256DigestTest.cs b/crypto/test/src/crypto/test/GOST3411_2012_256DigestTest.cs
index 4b48eab4f..3f3e04f7a 100644
--- a/crypto/test/src/crypto/test/GOST3411_2012_256DigestTest.cs
+++ b/crypto/test/src/crypto/test/GOST3411_2012_256DigestTest.cs
@@ -1,13 +1,10 @@
 using System;
-using System.Collections;
 
 using NUnit.Framework;
 
-using Org.BouncyCastle.Crypto;
 using Org.BouncyCastle.Crypto.Digests;
 using Org.BouncyCastle.Crypto.Macs;
 using Org.BouncyCastle.Crypto.Parameters;
-using Org.BouncyCastle.Crypto.Tests;
 using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.Encoders;
 
diff --git a/crypto/test/src/crypto/test/GOST3411_2012_512DigestTest.cs b/crypto/test/src/crypto/test/GOST3411_2012_512DigestTest.cs
index 7b4c0273a..bad1742ef 100644
--- a/crypto/test/src/crypto/test/GOST3411_2012_512DigestTest.cs
+++ b/crypto/test/src/crypto/test/GOST3411_2012_512DigestTest.cs
@@ -1,5 +1,4 @@
 using System;
-using System.Collections;
 
 using NUnit.Framework;
 
diff --git a/crypto/test/src/crypto/test/NistEccTest.cs b/crypto/test/src/crypto/test/NistEccTest.cs
index aaf4f666b..4269ef55d 100644
--- a/crypto/test/src/crypto/test/NistEccTest.cs
+++ b/crypto/test/src/crypto/test/NistEccTest.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 using System.Text.RegularExpressions;
 
@@ -33,9 +33,9 @@ namespace Org.BouncyCastle.Crypto.Tests
             }
         }
 
-        public IEnumerable CollectTestVectors()
+        public IEnumerable<object[]> CollectTestVectors()
         {
-            ArrayList testVectors = new ArrayList();
+            var testVectors = new List<object[]>();
             string curve = null;
             BigInteger k = null;
             BigInteger x = null;
@@ -72,7 +72,7 @@ namespace Org.BouncyCastle.Crypto.Tests
 
                     if (null != curve && null != k && null != x && null != y)
                     {
-                        testVectors.Add(new object[] {curve, k, x, y});
+                        testVectors.Add(new object[]{curve, k, x, y});
                         k = null;
                         x = null;
                         y = null;
diff --git a/crypto/test/src/crypto/test/cavp/CavpReader.cs b/crypto/test/src/crypto/test/cavp/CavpReader.cs
index dc32e0ff8..cbdaca155 100644
--- a/crypto/test/src/crypto/test/cavp/CavpReader.cs
+++ b/crypto/test/src/crypto/test/cavp/CavpReader.cs
@@ -1,31 +1,23 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
-using Org.BouncyCastle.Crypto.Digests;
-using Org.BouncyCastle.Crypto.Engines;
-using Org.BouncyCastle.Crypto.Macs;
 using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities.Collections;
 using Org.BouncyCastle.Utilities.Encoders;
 using Org.BouncyCastle.Utilities.Test;
 
 namespace Org.BouncyCastle.Crypto.Tests.Cavp
 {
-    internal class Vector : Hashtable
+    internal class Vector : Dictionary<string, object>
     {
-        private Hashtable mHeader = null;
+        private IDictionary<string, string> mHeader = null;
 
-        public Vector(Hashtable header)
+        public Vector(IDictionary<string, string> header)
         {
             this.mHeader = header;
         }
 
-        public Hashtable Header
-        {
-            get { return mHeader; }
-            set { this.mHeader = value; }
-        }
-
         public string ValueAsString(string name)
         {
             return this[name] as string;
@@ -33,7 +25,7 @@ namespace Org.BouncyCastle.Crypto.Tests.Cavp
 
         public string HeaderAsString(string name)
         {
-            return Header[name] as string;
+            return CollectionUtilities.GetValueOrNull(mHeader, name);
         }
 
         public byte[] ValueAsBytes(string name)
@@ -49,13 +41,8 @@ namespace Org.BouncyCastle.Crypto.Tests.Cavp
 
         public byte[] HeaderAsBytes(string name)
         {
-            string value = Header[name] as string;
-            if (value != null)
-            {
-                return Hex.Decode(value);
-            }
-
-            return null;
+            string value = HeaderAsString(name);
+            return value == null ? null : Hex.Decode(value);
         }
 
         public int ValueAsInt(string name)
@@ -79,10 +66,10 @@ namespace Org.BouncyCastle.Crypto.Tests.Cavp
 
     internal class CavpReader
     {
-        public static ArrayList ReadVectorFile(string name)
+        public static IList<Vector> ReadVectorFile(string name)
         {
-            ArrayList vectors = new ArrayList();
-            Hashtable header = null;
+            var vectors = new List<Vector>();
+            IDictionary<string, string> header = null;
             Vector currentVector = null;
 
             int headerState = 0;
@@ -148,7 +135,7 @@ namespace Org.BouncyCastle.Crypto.Tests.Cavp
                     //
                     if (headerState == 0 && line.StartsWith("[") && line.EndsWith("]"))
                     {
-                        header = new Hashtable();
+                        header = new Dictionary<string, string>();
                         headerState = 1;
                     }
 
diff --git a/crypto/test/src/crypto/test/cavp/KDFCounterTests.cs b/crypto/test/src/crypto/test/cavp/KDFCounterTests.cs
index 4cd20a93b..bce4c9516 100644
--- a/crypto/test/src/crypto/test/cavp/KDFCounterTests.cs
+++ b/crypto/test/src/crypto/test/cavp/KDFCounterTests.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using NUnit.Framework;
 
@@ -26,11 +26,11 @@ namespace Org.BouncyCastle.Crypto.Tests.Cavp
         public override void PerformTest()
         {
             string file = "KDFCTR_gen.rsp";
-            ArrayList vectors = CavpReader.ReadVectorFile(file);
+            var vectors = CavpReader.ReadVectorFile(file);
             ProcessVectors(file, vectors);
         }
 
-        private void ProcessVectors(string name, ArrayList vectors)
+        private void ProcessVectors(string name, IList<Vector> vectors)
         {
             foreach (Vector vector in vectors)
             {
diff --git a/crypto/test/src/crypto/test/cavp/KDFDoublePipelineTests.cs b/crypto/test/src/crypto/test/cavp/KDFDoublePipelineTests.cs
index 7d1558ce9..a995db884 100644
--- a/crypto/test/src/crypto/test/cavp/KDFDoublePipelineTests.cs
+++ b/crypto/test/src/crypto/test/cavp/KDFDoublePipelineTests.cs
@@ -1,5 +1,4 @@
 using System;
-using System.Collections;
 
 using NUnit.Framework;
 
@@ -28,7 +27,7 @@ namespace Org.BouncyCastle.Crypto.Tests.Cavp
         private void KdfDblPipelineNoCounterTest()
         {
             string file = "KDFDblPipelineNoCounter_gen.rsp";
-            ArrayList vectors = CavpReader.ReadVectorFile(file);
+            var vectors = CavpReader.ReadVectorFile(file);
 
             foreach (Vector vector in vectors)
             {
@@ -53,7 +52,7 @@ namespace Org.BouncyCastle.Crypto.Tests.Cavp
         private void KdfDblPipelineCounterTest()
         {
             string file = "KDFDblPipelineCounter_gen.rsp";
-            ArrayList vectors = CavpReader.ReadVectorFile(file);
+            var vectors = CavpReader.ReadVectorFile(file);
 
             foreach (Vector vector in vectors)
             {
diff --git a/crypto/test/src/crypto/test/cavp/KDFFeedbackCounterTests.cs b/crypto/test/src/crypto/test/cavp/KDFFeedbackCounterTests.cs
index 26789bf28..e734c99f0 100644
--- a/crypto/test/src/crypto/test/cavp/KDFFeedbackCounterTests.cs
+++ b/crypto/test/src/crypto/test/cavp/KDFFeedbackCounterTests.cs
@@ -1,5 +1,4 @@
 using System;
-using System.Collections;
 
 using NUnit.Framework;
 
@@ -28,7 +27,7 @@ namespace Org.BouncyCastle.Crypto.Tests.Cavp
         private void KdfFeedbackNoCounterTest()
         {
             string file = "KDFFeedbackNoCounter_gen.rsp";
-            ArrayList vectors = CavpReader.ReadVectorFile(file);
+            var vectors = CavpReader.ReadVectorFile(file);
 
             foreach (Vector vector in vectors)
             {
@@ -54,7 +53,7 @@ namespace Org.BouncyCastle.Crypto.Tests.Cavp
         private void KdfFeedbackCounterTest()
         {
             string file = "KDFFeedbackCounter_gen.rsp";
-            ArrayList vectors = CavpReader.ReadVectorFile(file);
+            var vectors = CavpReader.ReadVectorFile(file);
 
             foreach (Vector vector in vectors)
             {
diff --git a/crypto/test/src/math/ec/test/ECAlgorithmsTest.cs b/crypto/test/src/math/ec/test/ECAlgorithmsTest.cs
index dbbd0a328..419b022a7 100644
--- a/crypto/test/src/math/ec/test/ECAlgorithmsTest.cs
+++ b/crypto/test/src/math/ec/test/ECAlgorithmsTest.cs
@@ -1,12 +1,11 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using NUnit.Framework;
 
 using Org.BouncyCastle.Asn1.X9;
 using Org.BouncyCastle.Crypto.EC;
 using Org.BouncyCastle.Security;
-using Org.BouncyCastle.Utilities.Collections;
 
 namespace Org.BouncyCastle.Math.EC.Tests
 {
@@ -128,12 +127,12 @@ namespace Org.BouncyCastle.Math.EC.Tests
             return new BigInteger(x9.N.BitLength, Random);
         }
 
-        private IList GetTestCurves()
+        private IList<X9ECParameters> GetTestCurves()
         {
-            ArrayList x9s = new ArrayList();
-            ISet names = new HashSet(ECNamedCurveTable.Names);
-            names.AddAll(CustomNamedCurves.Names);
+            var names = new HashSet<string>(ECNamedCurveTable.Names);
+            names.UnionWith(CustomNamedCurves.Names);
 
+            var x9s = new List<X9ECParameters>();
             foreach (string name in names)
             {
                 X9ECParameters x9 = ECNamedCurveTable.GetByName(name);
@@ -151,7 +150,7 @@ namespace Org.BouncyCastle.Math.EC.Tests
             return x9s;
         }
 
-        private void AddTestCurves(IList x9s, X9ECParameters x9)
+        private void AddTestCurves(IList<X9ECParameters> x9s, X9ECParameters x9)
         {
             ECCurve curve = x9.Curve;
 
diff --git a/crypto/test/src/math/ec/test/ECPointPerformanceTest.cs b/crypto/test/src/math/ec/test/ECPointPerformanceTest.cs
index 059416427..18051226b 100644
--- a/crypto/test/src/math/ec/test/ECPointPerformanceTest.cs
+++ b/crypto/test/src/math/ec/test/ECPointPerformanceTest.cs
@@ -179,7 +179,7 @@ namespace Org.BouncyCastle.Math.EC.Tests
 
             names.Sort();
 
-            ISet oids = new HashSet();
+            var oids = new HashSet<DerObjectIdentifier>();
             foreach (string name in names)
             {
                 DerObjectIdentifier oid = ECNamedCurveTable.GetOid(name);
diff --git a/crypto/test/src/math/ec/test/ECPointTest.cs b/crypto/test/src/math/ec/test/ECPointTest.cs
index 4e3fc5832..7a833a413 100644
--- a/crypto/test/src/math/ec/test/ECPointTest.cs
+++ b/crypto/test/src/math/ec/test/ECPointTest.cs
@@ -7,7 +7,6 @@ using Org.BouncyCastle.Asn1.X9;
 using Org.BouncyCastle.Crypto.EC;
 using Org.BouncyCastle.Security;
 using Org.BouncyCastle.Utilities;
-using Org.BouncyCastle.Utilities.Collections;
 using Org.BouncyCastle.Utilities.Encoders;
 
 namespace Org.BouncyCastle.Math.EC.Tests
@@ -538,7 +537,7 @@ namespace Org.BouncyCastle.Math.EC.Tests
             names.AddRange(ECNamedCurveTable.Names);
             names.AddRange(CustomNamedCurves.Names);
 
-            ISet uniqNames = new HashSet(names);
+            var uniqNames = new HashSet<string>(names);
 
             foreach (string name in uniqNames)
             {
diff --git a/crypto/test/src/math/ec/test/FixedPointTest.cs b/crypto/test/src/math/ec/test/FixedPointTest.cs
index 433f956da..bc90bdfc3 100644
--- a/crypto/test/src/math/ec/test/FixedPointTest.cs
+++ b/crypto/test/src/math/ec/test/FixedPointTest.cs
@@ -27,7 +27,7 @@ namespace Org.BouncyCastle.Math.EC.Tests
             names.AddRange(ECNamedCurveTable.Names);
             names.AddRange(CustomNamedCurves.Names);
 
-            ISet uniqNames = new HashSet(names);
+            var uniqNames = new HashSet<string>(names);
 
             foreach (string name in uniqNames)
             {
diff --git a/crypto/test/src/openpgp/test/IgnoreMarkerPacketInCertificatesTest.cs b/crypto/test/src/openpgp/test/IgnoreMarkerPacketInCertificatesTest.cs
index 7b845d077..71196edae 100644
--- a/crypto/test/src/openpgp/test/IgnoreMarkerPacketInCertificatesTest.cs
+++ b/crypto/test/src/openpgp/test/IgnoreMarkerPacketInCertificatesTest.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 using System.Text;
 
@@ -71,12 +71,12 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
 
             PgpPublicKeyRing certificate = (PgpPublicKeyRing)objectFactory.NextPgpObject();
             IsEquals("Bob Babbage <bob@openpgp.example>", First(certificate.GetPublicKey().GetUserIds()));
-            IEnumerable publicKeys = certificate.GetPublicKeys();
-            IEnumerator publicKeyEnum = publicKeys.GetEnumerator();
+            var publicKeys = certificate.GetPublicKeys();
+            var publicKeyEnum = publicKeys.GetEnumerator();
             IsTrue(publicKeyEnum.MoveNext());
             PgpPublicKey primaryKey = (PgpPublicKey)publicKeyEnum.Current;
             IsEquals(new BigInteger("FBFCC82A015E7330", 16).LongValue, primaryKey.KeyId);
-            IEnumerable signatures = primaryKey.GetSignatures();
+            var signatures = primaryKey.GetSignatures();
             IsEquals(1, Count(signatures));
 
             IsTrue(publicKeyEnum.MoveNext());
@@ -94,19 +94,19 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
 			Assert.AreEqual(Name + ": Okay", resultText);
 		}
 
-        private int Count(IEnumerable e)
+        private int Count<T>(IEnumerable<T> e)
         {
             int count = 0;
-            foreach (object o in e)
+            foreach (T t in e)
             {
                 ++count;
             }
             return count;
         }
 
-        private object First(IEnumerable e)
+        private T First<T>(IEnumerable<T> e)
         {
-            IEnumerator enumerator = e.GetEnumerator();
+            var enumerator = e.GetEnumerator();
             IsTrue(enumerator.MoveNext());
             return enumerator.Current;
         }
diff --git a/crypto/test/src/openpgp/test/PGPClearSignedSignatureTest.cs b/crypto/test/src/openpgp/test/PGPClearSignedSignatureTest.cs
index 98762fab1..a6f03c06f 100644
--- a/crypto/test/src/openpgp/test/PGPClearSignedSignatureTest.cs
+++ b/crypto/test/src/openpgp/test/PGPClearSignedSignatureTest.cs
@@ -1,5 +1,4 @@
 using System;
-using System.Collections;
 using System.IO;
 using System.Text;
 
@@ -264,10 +263,9 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
 
 			sGen.InitSign(PgpSignature.CanonicalTextDocument, pgpPrivKey);
 
-			IEnumerator    it = pgpSecKey.PublicKey.GetUserIds().GetEnumerator();
-			if (it.MoveNext())
+			foreach (var userId in pgpSecKey.PublicKey.GetUserIds())
 			{
-				spGen.SetSignerUserId(false, (string)it.Current);
+				spGen.SetSignerUserId(false, userId);
 				sGen.SetHashedSubpackets(spGen.Generate());
 			}
 
diff --git a/crypto/test/src/openpgp/test/PGPDSATest.cs b/crypto/test/src/openpgp/test/PGPDSATest.cs
index 104f5d494..d5ef8b5e9 100644
--- a/crypto/test/src/openpgp/test/PGPDSATest.cs
+++ b/crypto/test/src/openpgp/test/PGPDSATest.cs
@@ -1,5 +1,4 @@
 using System;
-using System.Collections;
 using System.IO;
 using System.Text;
 
@@ -289,9 +288,9 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
 
             PgpSignatureSubpacketGenerator spGen = new PgpSignatureSubpacketGenerator();
 
-            IEnumerator enumerator = sKey.GetSecretKey().PublicKey.GetUserIds().GetEnumerator();
+            var enumerator = sKey.GetSecretKey().PublicKey.GetUserIds().GetEnumerator();
             enumerator.MoveNext();
-            string primaryUserId = (string) enumerator.Current;
+            string primaryUserId = enumerator.Current;
 
             spGen.SetSignerUserId(true, primaryUserId);
 
diff --git a/crypto/test/src/openpgp/test/PGPRSATest.cs b/crypto/test/src/openpgp/test/PGPRSATest.cs
index 534fb8c5d..9d1dedd95 100644
--- a/crypto/test/src/openpgp/test/PGPRSATest.cs
+++ b/crypto/test/src/openpgp/test/PGPRSATest.cs
@@ -1,5 +1,4 @@
 using System;
-using System.Collections;
 using System.IO;
 using System.Text;
 
@@ -539,14 +538,14 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
 
             AsymmetricKeyParameter pubKey = pgpPub.GetPublicKey().GetKey();
 
-            IEnumerator enumerator = pgpPub.GetPublicKey().GetUserIds().GetEnumerator();
-            enumerator.MoveNext();
-            string uid = (string) enumerator.Current;
+            var enumerator1= pgpPub.GetPublicKey().GetUserIds().GetEnumerator();
+            enumerator1.MoveNext();
+            string uid = enumerator1.Current;
 
 
-            enumerator = pgpPub.GetPublicKey().GetSignaturesForId(uid).GetEnumerator();
-            enumerator.MoveNext();
-            PgpSignature sig = (PgpSignature) enumerator.Current;
+            var enumerator2 = pgpPub.GetPublicKey().GetSignaturesForId(uid).GetEnumerator();
+            enumerator2.MoveNext();
+            PgpSignature sig = enumerator2.Current;
 
             sig.InitVerify(pgpPub.GetPublicKey());
 
@@ -830,14 +829,14 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
             PgpPublicKey key = secretKey.PublicKey;
 
 
-            enumerator = key.GetUserIds().GetEnumerator();
-            enumerator.MoveNext();
-            uid = (string) enumerator.Current;
+            var enumerator3 = key.GetUserIds().GetEnumerator();
+            enumerator3.MoveNext();
+            uid = enumerator3.Current;
 
 
-            enumerator = key.GetSignaturesForId(uid).GetEnumerator();
-            enumerator.MoveNext();
-            sig = (PgpSignature) enumerator.Current;
+            var enumerator4 = key.GetSignaturesForId(uid).GetEnumerator();
+            enumerator4.MoveNext();
+            sig = enumerator4.Current;
 
             sig.InitVerify(key);
 
@@ -875,9 +874,9 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
 
             key = tmpRing.GetPublicKey();
 
-            IEnumerator sgEnum = key.GetSignaturesOfType(PgpSignature.KeyRevocation).GetEnumerator();
+            var sgEnum = key.GetSignaturesOfType(PgpSignature.KeyRevocation).GetEnumerator();
             sgEnum.MoveNext();
-            sig = (PgpSignature) sgEnum.Current;
+            sig = sgEnum.Current;
 
             sig.InitVerify(key);
 
@@ -926,14 +925,14 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
             key.Encode(new UncloseableMemoryStream());
 
 
-            enumerator = key.GetUserIds().GetEnumerator();
-            enumerator.MoveNext();
-            uid = (string) enumerator.Current;
+            var enumerator5 = key.GetUserIds().GetEnumerator();
+            enumerator5.MoveNext();
+            uid = enumerator5.Current;
 
 
-            enumerator = key.GetSignaturesForId(uid).GetEnumerator();
-            enumerator.MoveNext();
-            sig = (PgpSignature) enumerator.Current;
+            var enumerator6 = key.GetSignaturesForId(uid).GetEnumerator();
+            enumerator6.MoveNext();
+            sig = enumerator6.Current;
 
             sig.InitVerify(key);
 
diff --git a/crypto/test/src/openpgp/test/PgpECDHTest.cs b/crypto/test/src/openpgp/test/PgpECDHTest.cs
index 711d917a7..aa4fc2117 100644
--- a/crypto/test/src/openpgp/test/PgpECDHTest.cs
+++ b/crypto/test/src/openpgp/test/PgpECDHTest.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 using System.Text;
 
@@ -249,9 +249,9 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
             }
         }
 
-        private static object First(IEnumerable e)
+        private static T First<T>(IEnumerable<T> e)
         {
-            IEnumerator n = e.GetEnumerator();
+            var n = e.GetEnumerator();
             Assert.IsTrue(n.MoveNext());
             return n.Current;
         }
diff --git a/crypto/test/src/openpgp/test/PgpECDsaTest.cs b/crypto/test/src/openpgp/test/PgpECDsaTest.cs
index 35e9a2332..c3611d5aa 100644
--- a/crypto/test/src/openpgp/test/PgpECDsaTest.cs
+++ b/crypto/test/src/openpgp/test/PgpECDsaTest.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 using System.Text;
 
@@ -176,9 +176,9 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
             }
         }
 
-        private static object First(IEnumerable e)
+        private static T First<T>(IEnumerable<T> e)
         {
-            IEnumerator n = e.GetEnumerator();
+            var n = e.GetEnumerator();
             Assert.IsTrue(n.MoveNext());
             return n.Current;
         }
diff --git a/crypto/test/src/openpgp/test/PgpKeyRingTest.cs b/crypto/test/src/openpgp/test/PgpKeyRingTest.cs
index efc47f881..a5dc4963b 100644
--- a/crypto/test/src/openpgp/test/PgpKeyRingTest.cs
+++ b/crypto/test/src/openpgp/test/PgpKeyRingTest.cs
@@ -1,5 +1,4 @@
 using System;
-using System.Collections;
 using System.IO;
 
 using NUnit.Framework;
@@ -2511,7 +2510,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
 
             foreach (PgpSecretKeyRing ring in secCol.GetKeyRings())
             {
-                IEnumerator e = ring.GetExtraPublicKeys().GetEnumerator();
+                var e = ring.GetExtraPublicKeys().GetEnumerator();
                 while (e.MoveNext())
                 {
                     ++count;
@@ -2528,13 +2527,13 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
             byte[] keyRing)
         {
             PgpPublicKeyRing pubRing = new PgpPublicKeyRing(keyRing);
-            IEnumerator en = pubRing.GetPublicKeys().GetEnumerator();
+            var en = pubRing.GetPublicKeys().GetEnumerator();
 
             if (en.MoveNext())
             {
                 PgpPublicKey key = (PgpPublicKey) en.Current;
 
-                IEnumerator sEn = key.GetSignatures().GetEnumerator();
+                var sEn = key.GetSignatures().GetEnumerator();
 
                 if (sEn.MoveNext())
                 {
diff --git a/crypto/test/src/openpgp/test/PgpSignatureInvalidVersionIgnoredTest.cs b/crypto/test/src/openpgp/test/PgpSignatureInvalidVersionIgnoredTest.cs
index 1cd1385ba..ef64a464a 100644
--- a/crypto/test/src/openpgp/test/PgpSignatureInvalidVersionIgnoredTest.cs
+++ b/crypto/test/src/openpgp/test/PgpSignatureInvalidVersionIgnoredTest.cs
@@ -1,5 +1,4 @@
 using System;
-using System.Collections;
 using System.IO;
 using System.Text;
 
diff --git a/crypto/test/src/pkcs/test/PKCS10Test.cs b/crypto/test/src/pkcs/test/PKCS10Test.cs
index 39b33e1b5..949045c8a 100644
--- a/crypto/test/src/pkcs/test/PKCS10Test.cs
+++ b/crypto/test/src/pkcs/test/PKCS10Test.cs
@@ -1,4 +1,4 @@
-using System.Collections;
+using System;
 using System.Collections.Generic;
 
 using NUnit.Framework;
diff --git a/crypto/test/src/pkcs/test/PKCS12StoreTest.cs b/crypto/test/src/pkcs/test/PKCS12StoreTest.cs
index a500e5e63..731070c08 100644
--- a/crypto/test/src/pkcs/test/PKCS12StoreTest.cs
+++ b/crypto/test/src/pkcs/test/PKCS12StoreTest.cs
@@ -1,5 +1,4 @@
 using System;
-using System.Collections;
 using System.Collections.Generic;
 using System.IO;
 
diff --git a/crypto/test/src/security/test/TestDotNetUtil.cs b/crypto/test/src/security/test/TestDotNetUtil.cs
index e2bb783ef..82cad46f1 100644
--- a/crypto/test/src/security/test/TestDotNetUtil.cs
+++ b/crypto/test/src/security/test/TestDotNetUtil.cs
@@ -1,5 +1,4 @@
 using System;
-using System.Collections;
 using System.Collections.Generic;
 using System.Security.Cryptography;
 using SystemX509 = System.Security.Cryptography.X509Certificates;
diff --git a/crypto/test/src/security/test/TestEncodings.cs b/crypto/test/src/security/test/TestEncodings.cs
index d83b2dda5..330054e84 100644
--- a/crypto/test/src/security/test/TestEncodings.cs
+++ b/crypto/test/src/security/test/TestEncodings.cs
@@ -1,15 +1,11 @@
 using System;
-using System.Collections;
-using System.Text;
 
 using NUnit.Framework;
 
 using Org.BouncyCastle.Asn1.Pkcs;
 using Org.BouncyCastle.Asn1.X509;
 using Org.BouncyCastle.Crypto;
-using Org.BouncyCastle.Crypto.Generators;
 using Org.BouncyCastle.Crypto.Parameters;
-using Org.BouncyCastle.Crypto.Signers;
 using Org.BouncyCastle.Math;
 using Org.BouncyCastle.Math.EC;
 using Org.BouncyCastle.Pkcs;
diff --git a/crypto/test/src/security/test/TestSignerUtil.cs b/crypto/test/src/security/test/TestSignerUtil.cs
index f075526b0..2c569d030 100644
--- a/crypto/test/src/security/test/TestSignerUtil.cs
+++ b/crypto/test/src/security/test/TestSignerUtil.cs
@@ -1,20 +1,13 @@
 using System;
-using System.Collections;
-using System.Globalization;
-using System.Text;
 
 using NUnit.Framework;
 
 using Org.BouncyCastle.Asn1.CryptoPro;
-using Org.BouncyCastle.Asn1.Pkcs;
-using Org.BouncyCastle.Asn1.X509;
 using Org.BouncyCastle.Math;
 using Org.BouncyCastle.Math.EC;
 using Org.BouncyCastle.Crypto;
 using Org.BouncyCastle.Crypto.Generators;
 using Org.BouncyCastle.Crypto.Parameters;
-using Org.BouncyCastle.Crypto.Signers;
-using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.Encoders;
 
 namespace Org.BouncyCastle.Security.Tests
@@ -142,11 +135,8 @@ namespace Org.BouncyCastle.Security.Tests
             {
                 ISigner signer = SignerUtilities.GetSigner(algorithm);
 
-#if PORTABLE
                 string upper = algorithm.ToUpperInvariant();
-#else
-                string upper = algorithm.ToUpper(CultureInfo.InvariantCulture);
-#endif
+
                 int withPos = upper.LastIndexOf("WITH");
 
                 string cipherName = withPos < 0
diff --git a/crypto/test/src/test/BlockCipherTest.cs b/crypto/test/src/test/BlockCipherTest.cs
index ff6f45e74..b57d62d94 100644
--- a/crypto/test/src/test/BlockCipherTest.cs
+++ b/crypto/test/src/test/BlockCipherTest.cs
@@ -1,4 +1,5 @@
 using System;
+using System.Collections.Generic;
 using System.Globalization;
 using System.IO;
 
@@ -9,8 +10,6 @@ using Org.BouncyCastle.Crypto;
 using Org.BouncyCastle.Crypto.IO;
 using Org.BouncyCastle.Crypto.Parameters;
 using Org.BouncyCastle.Security;
-using Org.BouncyCastle.Utilities;
-using Org.BouncyCastle.Utilities.Collections;
 using Org.BouncyCastle.Utilities.Encoders;
 using Org.BouncyCastle.Utilities.Test;
 
@@ -24,8 +23,8 @@ namespace Org.BouncyCastle.Tests
     public class BlockCipherTest
         : SimpleTest
     {
-        private static readonly ISet validModes = CollectionUtilities.ReadOnly(
-            new HashSet(new string[]{ "CBC", "CCM", "CFB", "CTR", "CTS", "EAX", "ECB", "GCM", "OCB", "OFB" }));
+        private static readonly ISet<string> ValidModes =
+            new HashSet<string>(){ "CBC", "CCM", "CFB", "CTR", "CTS", "EAX", "ECB", "GCM", "OCB", "OFB" };
 
         private static readonly string[] cipherTests1 =
         {
@@ -436,7 +435,7 @@ namespace Org.BouncyCastle.Tests
             int pos = mode.IndexOfAny(new char[]{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' });
             string baseMode = pos < 0 ? mode : mode.Substring(0, pos);
 
-            if (!validModes.Contains(baseMode))
+            if (!ValidModes.Contains(baseMode))
                 throw new Exception("Unhandled mode: " + mode);
 
             if (baseMode == "CCM")
diff --git a/crypto/test/src/test/CertPathTest.cs b/crypto/test/src/test/CertPathTest.cs
index 869ffd6a0..be1df89a7 100644
--- a/crypto/test/src/test/CertPathTest.cs
+++ b/crypto/test/src/test/CertPathTest.cs
@@ -1,5 +1,4 @@
 using System;
-using System.Collections;
 using System.Collections.Generic;
 using System.IO;
 
diff --git a/crypto/test/src/test/CertPathValidatorTest.cs b/crypto/test/src/test/CertPathValidatorTest.cs
index 88ffe7938..3c4577d59 100644
--- a/crypto/test/src/test/CertPathValidatorTest.cs
+++ b/crypto/test/src/test/CertPathValidatorTest.cs
@@ -1,5 +1,4 @@
 using System;
-using System.Collections;
 using System.Collections.Generic;
 
 using NUnit.Framework;
diff --git a/crypto/test/src/test/CertTest.cs b/crypto/test/src/test/CertTest.cs
index 7fb2c89c1..b286263a7 100644
--- a/crypto/test/src/test/CertTest.cs
+++ b/crypto/test/src/test/CertTest.cs
@@ -1,5 +1,4 @@
 using System;
-using System.Collections;
 using System.Collections.Generic;
 using System.IO;
 using System.Text;
@@ -2485,7 +2484,7 @@ namespace Org.BouncyCastle.Tests
 
             MemoryStream input = new MemoryStream(Streams.ReadAll(GetTestDataAsStream("cert_chain.data")), false);
 
-            ISet certs2 = new HashSet();
+            var certs2 = new HashSet<X509Certificate>();
             while (input.Position < input.Length)
             {
                 X509Certificate c = fact.ReadCertificate(input);
@@ -2499,7 +2498,7 @@ namespace Org.BouncyCastle.Tests
             }
             IsTrue("certs size <cr><nl>", certs1.Count == certs2.Count);
 
-            certs2.RemoveAll(certs1);
+            certs2.ExceptWith(certs1);
             IsTrue("collection not empty", certs2.Count == 0);
         }
 
@@ -2523,7 +2522,7 @@ namespace Org.BouncyCastle.Tests
 
             MemoryStream input = new MemoryStream(Streams.ReadAll(GetTestDataAsStream("cert_chain_nl.data")), false);
 
-            ISet certs2 = new HashSet();
+            var certs2 = new HashSet<X509Certificate>();
             while (input.Position < input.Length)
             {
                 X509Certificate c = fact.ReadCertificate(input);
@@ -2537,7 +2536,7 @@ namespace Org.BouncyCastle.Tests
             }
             IsTrue("certs size <nl>", certs1.Count == certs2.Count);
 
-            certs2.RemoveAll(certs1);
+            certs2.ExceptWith(certs1);
             IsTrue("collection not empty", certs2.Count == 0);
         }
 
diff --git a/crypto/test/src/test/NamedCurveTest.cs b/crypto/test/src/test/NamedCurveTest.cs
index c5c3ca74e..7f5332adf 100644
--- a/crypto/test/src/test/NamedCurveTest.cs
+++ b/crypto/test/src/test/NamedCurveTest.cs
@@ -22,8 +22,10 @@ namespace Org.BouncyCastle.Tests
     public class NamedCurveTest
         : SimpleTest
     {
-//		private static readonly Hashtable CurveNames = new Hashtable();
-//		private static readonly Hashtable CurveAliases = new Hashtable();
+//		private static readonly Dictionary<string, sring> CurveNames =
+//		    new Dictionary<string, sring>(StringComparer.OrdinalIgnoreCase);
+//		private static readonly Dictionary<string, sring> CurveAliases =
+//		    new Dictionary<string, sring>(StringComparer.OrdinalIgnoreCase);
 //
 //		static NamedCurveTest()
 //		{
diff --git a/crypto/test/src/test/NistCertPathTest.cs b/crypto/test/src/test/NistCertPathTest.cs
index 42f9895e8..f859ada0a 100644
--- a/crypto/test/src/test/NistCertPathTest.cs
+++ b/crypto/test/src/test/NistCertPathTest.cs
@@ -1,5 +1,4 @@
 using System;
-using System.Collections;
 using System.Collections.Generic;
 using System.Text;
 
@@ -72,7 +71,7 @@ namespace Org.BouncyCastle.Tests
 		private X509Crl trustedCRL;
 		private ISet<TrustAnchor> trustedSet;
 		private int testCount;
-		private IList testFail;
+		private IList<string> testFail;
 		private StringBuilder resultBuf;
 
 		public override string Name
@@ -268,7 +267,7 @@ namespace Org.BouncyCastle.Tests
 
 				trustedSet.Add(new TrustAnchor(trustedCert, _ncBytes));
 				testCount = 0;
-				testFail = new ArrayList();
+				testFail = new List<string>();
 				resultBuf = new StringBuilder("\n");
 			}
 			catch (Exception ex)
diff --git a/crypto/test/src/test/PKCS10CertRequestTest.cs b/crypto/test/src/test/PKCS10CertRequestTest.cs
index fb913d7de..1ec7c904e 100644
--- a/crypto/test/src/test/PKCS10CertRequestTest.cs
+++ b/crypto/test/src/test/PKCS10CertRequestTest.cs
@@ -1,5 +1,4 @@
 using System;
-using System.Collections;
 using System.Collections.Generic;
 using NUnit.Framework;
 
diff --git a/crypto/test/src/test/PkixPolicyMappingTest.cs b/crypto/test/src/test/PkixPolicyMappingTest.cs
index 5ca33bf6a..4dbfe0ad5 100644
--- a/crypto/test/src/test/PkixPolicyMappingTest.cs
+++ b/crypto/test/src/test/PkixPolicyMappingTest.cs
@@ -1,5 +1,4 @@
 using System;
-using System.Collections;
 using System.Collections.Generic;
 
 using NUnit.Framework;
diff --git a/crypto/test/src/test/PkixTest.cs b/crypto/test/src/test/PkixTest.cs
index 554d4c64f..5f321022c 100644
--- a/crypto/test/src/test/PkixTest.cs
+++ b/crypto/test/src/test/PkixTest.cs
@@ -1,7 +1,4 @@
 using System;
-using System.IO;
-using System.Collections;
-using System.Text;
 
 using NUnit.Framework;
 
diff --git a/crypto/test/src/test/X509StoreTest.cs b/crypto/test/src/test/X509StoreTest.cs
index 0a5fff6f1..aada53e4e 100644
--- a/crypto/test/src/test/X509StoreTest.cs
+++ b/crypto/test/src/test/X509StoreTest.cs
@@ -1,7 +1,5 @@
 using System;
-using System.Collections;
 using System.Collections.Generic;
-using System.IO;
 
 using NUnit.Framework;
 
@@ -137,7 +135,7 @@ namespace Org.BouncyCastle.Tests
 
 			X509CrlStoreSelector targetConstraintsCRL = new X509CrlStoreSelector();
 
-			ArrayList issuers = new ArrayList();
+			var issuers = new List<X509Name>();
 			issuers.Add(rootCrl.IssuerDN);
 			targetConstraintsCRL.Issuers = issuers;
 
diff --git a/crypto/test/src/test/nist/NistCertPathTest.cs b/crypto/test/src/test/nist/NistCertPathTest.cs
index 89565217c..4a6391e8f 100644
--- a/crypto/test/src/test/nist/NistCertPathTest.cs
+++ b/crypto/test/src/test/nist/NistCertPathTest.cs
@@ -1,5 +1,4 @@
 using System;
-using System.Collections;
 using System.Collections.Generic;
 using System.IO;
 
@@ -35,8 +34,8 @@ namespace Org.BouncyCastle.Tests.Nist
 		private static readonly string NIST_TEST_POLICY_2 = "2.16.840.1.101.3.2.1.48.2";
 		private static readonly string NIST_TEST_POLICY_3 = "2.16.840.1.101.3.2.1.48.3";
 
-		private static readonly IDictionary certs = new Hashtable();
-        private static readonly IDictionary crls = new Hashtable();
+		private static readonly Dictionary<string, X509Certificate> Certs = new Dictionary<string, X509Certificate>();
+		private static readonly Dictionary<string, X509Crl> Crls = new Dictionary<string, X509Crl>();
 
         private static readonly HashSet<string> noPolicies = new HashSet<string>();
         private static readonly HashSet<string> anyPolicy = new HashSet<string>();
@@ -758,52 +757,28 @@ namespace Org.BouncyCastle.Tests.Nist
 
         private X509Certificate LoadCert(string certName)
         {
-            X509Certificate cert = (X509Certificate)certs[certName];
-            if (null != cert)
-                return cert;
+			if (Certs.TryGetValue(certName, out var cachedCert))
+				return cachedCert;
 
-            Stream fs = null;
-
-            try
-            {
-                fs = SimpleTest.GetTestDataAsStream("PKITS.certs." + certName + ".crt");
-                cert = new X509CertificateParser().ReadCertificate(fs);
-                certs[certName] = cert;
-                return cert;
-            }
-            catch (Exception e)
-            {
-                throw new InvalidOperationException("exception loading certificate " + certName + ": " + e);
-            }
-            finally
+			using (Stream fs = SimpleTest.GetTestDataAsStream("PKITS.certs." + certName + ".crt"))
             {
-                fs.Close();
-            }
+				var cert = new X509CertificateParser().ReadCertificate(fs);
+				Certs[certName] = cert;
+				return cert;
+			}
         }
 
         private X509Crl LoadCrl(string crlName)
         {
-            X509Crl crl = (X509Crl)crls[crlName];
-            if (null != crl)
-                return crl;
-
-            Stream fs = null;
+			if (Crls.TryGetValue(crlName, out var cachedCrl))
+				return cachedCrl;
 
-            try
-            {
-                fs = SimpleTest.GetTestDataAsStream("PKITS.crls." + crlName + ".crl");
-                crl = new X509CrlParser().ReadCrl(fs);
-                crls[crlName] = crl;
-                return crl;
-            }
-            catch (Exception)
-            {
-                throw new InvalidOperationException("exception loading CRL: " + crlName);
-            }
-            finally
-            {
-                fs.Close();
-            }
+			using (Stream fs = SimpleTest.GetTestDataAsStream("PKITS.crls." + crlName + ".crl"))
+			{
+				var crl = new X509CrlParser().ReadCrl(fs);
+				Crls[crlName] = crl;
+				return crl;
+			}
         }
 
 		private TrustAnchor GetTrustAnchor(string trustAnchorName)
diff --git a/crypto/test/src/test/nist/NistCertPathTest2.cs b/crypto/test/src/test/nist/NistCertPathTest2.cs
index 244f9f9c5..1bc40e805 100644
--- a/crypto/test/src/test/nist/NistCertPathTest2.cs
+++ b/crypto/test/src/test/nist/NistCertPathTest2.cs
@@ -1,7 +1,5 @@
 using System;
-using System.Collections;
 using System.Collections.Generic;
-using System.IO;
 
 using NUnit.Framework;
 
@@ -28,15 +26,16 @@ namespace Org.BouncyCastle.Tests.Nist
         private static readonly string NIST_TEST_POLICY_2 = "2.16.840.1.101.3.2.1.48.2";
         private static readonly string NIST_TEST_POLICY_3 = "2.16.840.1.101.3.2.1.48.3";
 
-		private static readonly IDictionary certs = new Hashtable();
-		private static readonly IDictionary crls = new Hashtable();
+		private static readonly IDictionary<string, X509Certificate> m_certs =
+            new Dictionary<string, X509Certificate>();
+		private static readonly IDictionary<string, X509Crl> m_crls = new Dictionary<string, X509Crl>();
 
-        private static readonly ISet noPolicies = new HashSet();
-        private static readonly ISet anyPolicy = new HashSet();
-        private static readonly ISet nistTestPolicy1 = new HashSet();
-        private static readonly ISet nistTestPolicy2 = new HashSet();
-        private static readonly ISet nistTestPolicy3 = new HashSet();
-        private static readonly ISet nistTestPolicy1And2 = new HashSet();
+        private static readonly ISet<string> noPolicies = new HashSet<string>();
+        private static readonly ISet<string> anyPolicy = new HashSet<string>();
+        private static readonly ISet<string> nistTestPolicy1 = new HashSet<string>();
+        private static readonly ISet<string> nistTestPolicy2 = new HashSet<string>();
+        private static readonly ISet<string> nistTestPolicy3 = new HashSet<string>();
+        private static readonly ISet<string> nistTestPolicy1And2 = new HashSet<string>();
 
         static NistCertPathTest2()
 		{
@@ -425,52 +424,28 @@ namespace Org.BouncyCastle.Tests.Nist
 
         private X509Certificate LoadCert(string certName)
 		{
-			X509Certificate cert = (X509Certificate)certs[certName];
-			if (null != cert)
-				return cert;
+            if (m_certs.TryGetValue(certName, out var cachedCert))
+                return cachedCert;
 
-            Stream fs = null;
-
-			try
-			{
-				fs = SimpleTest.GetTestDataAsStream("PKITS.certs." + certName + ".crt");
-				cert = new X509CertificateParser().ReadCertificate(fs);
-				certs[certName] = cert;
-				return cert;
-			}
-			catch (Exception e)
-			{
-				throw new InvalidOperationException("exception loading certificate " + certName + ": " + e);
-			}
-			finally
-			{
-				fs.Close();
-			}
+            using (var fs = SimpleTest.GetTestDataAsStream("PKITS.certs." + certName + ".crt"))
+            {
+                var cert = new X509CertificateParser().ReadCertificate(fs);
+                m_certs[certName] = cert;
+                return cert;
+            }
 		}
 
 		private X509Crl LoadCrl(string crlName)
 		{
-			X509Crl crl = (X509Crl)crls[crlName];
-			if (null != crl)
-				return crl;
+            if (m_crls.TryGetValue(crlName, out var cachedCrl))
+                return cachedCrl;
 
-            Stream fs = null;
-
-			try
-			{
-				fs = SimpleTest.GetTestDataAsStream("PKITS.crls." + crlName + ".crl");
-				crl = new X509CrlParser().ReadCrl(fs);
-				crls[crlName] = crl;
-				return crl;
-			}
-			catch (Exception)
-			{
-				throw new InvalidOperationException("exception loading CRL: " + crlName);
-			}
-			finally
-			{
-				fs.Close();
-			}
+            using (var fs = SimpleTest.GetTestDataAsStream("PKITS.crls." + crlName + ".crl"))
+            {
+                var crl = new X509CrlParser().ReadCrl(fs);
+                m_crls[crlName] = crl;
+                return crl;
+            }
 		}
 
         private TrustAnchor GetTrustAnchor(string trustAnchorName)
diff --git a/crypto/test/src/tls/test/MockDatagramAssociation.cs b/crypto/test/src/tls/test/MockDatagramAssociation.cs
index 3e0c0f52b..ef317c7b6 100644
--- a/crypto/test/src/tls/test/MockDatagramAssociation.cs
+++ b/crypto/test/src/tls/test/MockDatagramAssociation.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.Threading;
 
 using Org.BouncyCastle.Utilities;
@@ -15,8 +15,8 @@ namespace Org.BouncyCastle.Tls.Tests
         {
             this.m_mtu = mtu;
 
-            IList clientQueue = new ArrayList();
-            IList serverQueue = new ArrayList();
+            var clientQueue = new List<byte[]>();
+            var serverQueue = new List<byte[]>();
 
             this.m_client = new MockDatagramTransport(this, clientQueue, serverQueue);
             this.m_server = new MockDatagramTransport(this, serverQueue, clientQueue);
@@ -36,9 +36,10 @@ namespace Org.BouncyCastle.Tls.Tests
             : DatagramTransport
         {
             private readonly MockDatagramAssociation m_outer;
-            private IList m_receiveQueue, m_sendQueue;
+            private IList<byte[]> m_receiveQueue, m_sendQueue;
 
-            internal MockDatagramTransport(MockDatagramAssociation outer, IList receiveQueue, IList sendQueue)
+            internal MockDatagramTransport(MockDatagramAssociation outer, IList<byte[]> receiveQueue,
+                IList<byte[]> sendQueue)
             {
                 this.m_outer = outer;
                 this.m_receiveQueue = receiveQueue;
@@ -74,7 +75,7 @@ namespace Org.BouncyCastle.Tls.Tests
                             return -1;
                     }
 
-                    byte[] packet = (byte[])m_receiveQueue[0];
+                    byte[] packet = m_receiveQueue[0];
                     m_receiveQueue.RemoveAt(0);
                     int copyLength = System.Math.Min(len, packet.Length);
                     Array.Copy(packet, 0, buf, off, copyLength);
diff --git a/crypto/test/src/tsp/test/NewTspTest.cs b/crypto/test/src/tsp/test/NewTspTest.cs
index c188cb26a..f6d45ef09 100644
--- a/crypto/test/src/tsp/test/NewTspTest.cs
+++ b/crypto/test/src/tsp/test/NewTspTest.cs
@@ -1,5 +1,4 @@
 using System;
-using System.Collections;
 using System.Collections.Generic;
 using System.IO;
 
@@ -125,19 +124,19 @@ namespace Org.BouncyCastle.Tsp.Tests
 
 			try
 			{
-				request.Validate(new ArrayList(), new ArrayList(), new ArrayList());
+				request.Validate(new List<string>(), new List<string>(), new List<string>());
 				Assert.Fail("expected exception");
 			} catch(Exception ex)
             {
 				Assert.True("request contains unknown algorithm" == ex.Message);
             }
 
-			ArrayList algorithms = new ArrayList();
+			var algorithms = new List<string>();
 			algorithms.Add(TspAlgorithms.Sha1);
 
 			try
 			{
-				request.Validate(algorithms, new ArrayList(), new ArrayList());
+				request.Validate(algorithms, new List<string>(), new List<string>());
 				Assert.Fail("no exception");
 			}
 			catch (Exception e)
@@ -145,14 +144,14 @@ namespace Org.BouncyCastle.Tsp.Tests
 				Assert.IsTrue(e.Message == "request contains unknown policy");
 			}
 
-			ArrayList policies = new ArrayList();
+			var policies = new List<string>();
 
 			// Testing only do not use in real world.
 			policies.Add("2.5.29.56");
 
 			try
 			{
-				request.Validate(algorithms, policies, new ArrayList());
+				request.Validate(algorithms, policies, new List<string>());
 				Assert.Fail("no exception");
 			}
 			catch (Exception e)
@@ -160,7 +159,7 @@ namespace Org.BouncyCastle.Tsp.Tests
 				Assert.IsTrue(e.Message == "request contains unknown extension");
 			}
 
-			ArrayList extensions = new ArrayList();
+			var extensions = new List<string>();
 
 			// Testing only do not use in real world/
 			extensions.Add("1.3.6.1.5.5.7.1.2");
@@ -197,10 +196,10 @@ namespace Org.BouncyCastle.Tsp.Tests
 			TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator();
 			TimeStampRequest request = reqGen.Generate(TspAlgorithms.Sha1, new byte[20]);
 
-			ArrayList algorithms = new ArrayList();
+			var algorithms = new List<string>();
 			algorithms.Add(TspAlgorithms.Sha1);
 
-			request.Validate(algorithms, new ArrayList(), new ArrayList());
+			request.Validate(algorithms, new List<string>(), new List<string>());
 
 			Assert.False(request.CertReq);
 
@@ -423,7 +422,8 @@ namespace Org.BouncyCastle.Tsp.Tests
 			reqGen.SetReqPolicy("1.1");
 			TimeStampRequest request = reqGen.Generate(TspAlgorithms.Sha1, new byte[20]);
 
-			TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TspAlgorithms.Allowed, new ArrayList());
+			TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TspAlgorithms.Allowed,
+				new List<string>());
 
 			TimeStampResponse tsResp = tsRespGen.Generate(request, BigInteger.ValueOf(23), DateTime.UtcNow);
 
diff --git a/crypto/test/src/tsp/test/TSPTest.cs b/crypto/test/src/tsp/test/TSPTest.cs
index 06c20e4bd..99e11046f 100644
--- a/crypto/test/src/tsp/test/TSPTest.cs
+++ b/crypto/test/src/tsp/test/TSPTest.cs
@@ -1,5 +1,4 @@
 using System;
-using System.Collections;
 using System.Collections.Generic;
 
 using NUnit.Framework;
@@ -267,7 +266,8 @@ namespace Org.BouncyCastle.Tsp.Tests
 
 			TimeStampRequest request = reqGen.Generate(TspAlgorithms.Sha1, new byte[20]);
 
-			TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TspAlgorithms.Allowed, new ArrayList());
+			TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TspAlgorithms.Allowed,
+				new List<string>());
 
 			TimeStampResponse tsResp = tsRespGen.Generate(request, BigInteger.ValueOf(23), DateTime.UtcNow);
 
diff --git a/crypto/test/src/tsp/test/TSPTestUtil.cs b/crypto/test/src/tsp/test/TSPTestUtil.cs
index 20eb7e228..abe153ac1 100644
--- a/crypto/test/src/tsp/test/TSPTestUtil.cs
+++ b/crypto/test/src/tsp/test/TSPTestUtil.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.Text;
 
 using Org.BouncyCastle.Asn1;
@@ -59,18 +59,18 @@ namespace Org.BouncyCastle.Tsp.Tests
 		public static readonly string EncryptionGost3410 = CryptoProObjectIdentifiers.GostR3410x94.Id;
 		public static readonly string EncryptionECGost3410 = CryptoProObjectIdentifiers.GostR3410x2001.Id;
 
-		private static readonly IDictionary encryptionAlgs = new Hashtable();
-		private static readonly IDictionary digestAlgs = new Hashtable();
-		private static readonly IDictionary digestAliases = new Hashtable();
+		private static readonly Dictionary<string, string> EncryptionAlgs = new Dictionary<string, string>();
+		private static readonly Dictionary<string, string> DigestAlgs = new Dictionary<string, string>();
+		private static readonly Dictionary<string, string[]> DigestAliases = new Dictionary<string, string[]>();
 
-		private static readonly ISet noParams = new HashSet();
-		private static readonly IDictionary ecAlgorithms = new Hashtable();
+		private static readonly ISet<string> NoParams = new HashSet<string>();
+		private static readonly Dictionary<string, string> ECAlgorithms = new Dictionary<string, string>();
 
 		private static void AddEntries(DerObjectIdentifier oid, string digest, string encryption)
 		{
 			string alias = oid.Id;
-			digestAlgs.Add(alias, digest);
-			encryptionAlgs.Add(alias, encryption);
+			DigestAlgs.Add(alias, digest);
+			EncryptionAlgs.Add(alias, encryption);
 		}
 
 		static TspTestUtil()
@@ -131,49 +131,49 @@ namespace Org.BouncyCastle.Tsp.Tests
 			AddEntries(EacObjectIdentifiers.id_TA_RSA_PSS_SHA_1, "SHA1", "RSAandMGF1");
 			AddEntries(EacObjectIdentifiers.id_TA_RSA_PSS_SHA_256, "SHA256", "RSAandMGF1");
 
-			encryptionAlgs.Add(X9ObjectIdentifiers.IdDsa.Id, "DSA");
-			encryptionAlgs.Add(PkcsObjectIdentifiers.RsaEncryption.Id, "RSA");
-			encryptionAlgs.Add(TeleTrusTObjectIdentifiers.TeleTrusTRsaSignatureAlgorithm.Id, "RSA");
-			encryptionAlgs.Add(X509ObjectIdentifiers.IdEARsa.Id, "RSA");
-			encryptionAlgs.Add(EncryptionRsaPss, "RSAandMGF1");
-			encryptionAlgs.Add(CryptoProObjectIdentifiers.GostR3410x94.Id, "GOST3410");
-			encryptionAlgs.Add(CryptoProObjectIdentifiers.GostR3410x2001.Id, "ECGOST3410");
-			encryptionAlgs.Add("1.3.6.1.4.1.5849.1.6.2", "ECGOST3410");
-			encryptionAlgs.Add("1.3.6.1.4.1.5849.1.1.5", "GOST3410");
-
-			digestAlgs.Add(PkcsObjectIdentifiers.MD2.Id, "MD2");
-			digestAlgs.Add(PkcsObjectIdentifiers.MD4.Id, "MD4");
-			digestAlgs.Add(PkcsObjectIdentifiers.MD5.Id, "MD5");
-			digestAlgs.Add(OiwObjectIdentifiers.IdSha1.Id, "SHA1");
-			digestAlgs.Add(NistObjectIdentifiers.IdSha224.Id, "SHA224");
-			digestAlgs.Add(NistObjectIdentifiers.IdSha256.Id, "SHA256");
-			digestAlgs.Add(NistObjectIdentifiers.IdSha384.Id, "SHA384");
-			digestAlgs.Add(NistObjectIdentifiers.IdSha512.Id, "SHA512");
-			digestAlgs.Add(TeleTrusTObjectIdentifiers.RipeMD128.Id, "RIPEMD128");
-			digestAlgs.Add(TeleTrusTObjectIdentifiers.RipeMD160.Id, "RIPEMD160");
-			digestAlgs.Add(TeleTrusTObjectIdentifiers.RipeMD256.Id, "RIPEMD256");
-			digestAlgs.Add(CryptoProObjectIdentifiers.GostR3411.Id, "GOST3411");
-			digestAlgs.Add("1.3.6.1.4.1.5849.1.2.1", "GOST3411");
-
-			digestAliases.Add("SHA1", new string[] { "SHA-1" });
-			digestAliases.Add("SHA224", new string[] { "SHA-224" });
-			digestAliases.Add("SHA256", new string[] { "SHA-256" });
-			digestAliases.Add("SHA384", new string[] { "SHA-384" });
-			digestAliases.Add("SHA512", new string[] { "SHA-512" });
-
-			noParams.Add(EncryptionDsa);
+			EncryptionAlgs.Add(X9ObjectIdentifiers.IdDsa.Id, "DSA");
+			EncryptionAlgs.Add(PkcsObjectIdentifiers.RsaEncryption.Id, "RSA");
+			EncryptionAlgs.Add(TeleTrusTObjectIdentifiers.TeleTrusTRsaSignatureAlgorithm.Id, "RSA");
+			EncryptionAlgs.Add(X509ObjectIdentifiers.IdEARsa.Id, "RSA");
+			EncryptionAlgs.Add(EncryptionRsaPss, "RSAandMGF1");
+			EncryptionAlgs.Add(CryptoProObjectIdentifiers.GostR3410x94.Id, "GOST3410");
+			EncryptionAlgs.Add(CryptoProObjectIdentifiers.GostR3410x2001.Id, "ECGOST3410");
+			EncryptionAlgs.Add("1.3.6.1.4.1.5849.1.6.2", "ECGOST3410");
+			EncryptionAlgs.Add("1.3.6.1.4.1.5849.1.1.5", "GOST3410");
+
+			DigestAlgs.Add(PkcsObjectIdentifiers.MD2.Id, "MD2");
+			DigestAlgs.Add(PkcsObjectIdentifiers.MD4.Id, "MD4");
+			DigestAlgs.Add(PkcsObjectIdentifiers.MD5.Id, "MD5");
+			DigestAlgs.Add(OiwObjectIdentifiers.IdSha1.Id, "SHA1");
+			DigestAlgs.Add(NistObjectIdentifiers.IdSha224.Id, "SHA224");
+			DigestAlgs.Add(NistObjectIdentifiers.IdSha256.Id, "SHA256");
+			DigestAlgs.Add(NistObjectIdentifiers.IdSha384.Id, "SHA384");
+			DigestAlgs.Add(NistObjectIdentifiers.IdSha512.Id, "SHA512");
+			DigestAlgs.Add(TeleTrusTObjectIdentifiers.RipeMD128.Id, "RIPEMD128");
+			DigestAlgs.Add(TeleTrusTObjectIdentifiers.RipeMD160.Id, "RIPEMD160");
+			DigestAlgs.Add(TeleTrusTObjectIdentifiers.RipeMD256.Id, "RIPEMD256");
+			DigestAlgs.Add(CryptoProObjectIdentifiers.GostR3411.Id, "GOST3411");
+			DigestAlgs.Add("1.3.6.1.4.1.5849.1.2.1", "GOST3411");
+
+			DigestAliases.Add("SHA1", new string[] { "SHA-1" });
+			DigestAliases.Add("SHA224", new string[] { "SHA-224" });
+			DigestAliases.Add("SHA256", new string[] { "SHA-256" });
+			DigestAliases.Add("SHA384", new string[] { "SHA-384" });
+			DigestAliases.Add("SHA512", new string[] { "SHA-512" });
+
+			NoParams.Add(EncryptionDsa);
 			//noParams.Add(EncryptionECDsa);
-			noParams.Add(EncryptionECDsaWithSha1);
-			noParams.Add(EncryptionECDsaWithSha224);
-			noParams.Add(EncryptionECDsaWithSha256);
-			noParams.Add(EncryptionECDsaWithSha384);
-			noParams.Add(EncryptionECDsaWithSha512);
-
-			ecAlgorithms.Add(DigestSha1, EncryptionECDsaWithSha1);
-			ecAlgorithms.Add(DigestSha224, EncryptionECDsaWithSha224);
-			ecAlgorithms.Add(DigestSha256, EncryptionECDsaWithSha256);
-			ecAlgorithms.Add(DigestSha384, EncryptionECDsaWithSha384);
-			ecAlgorithms.Add(DigestSha512, EncryptionECDsaWithSha512);
+			NoParams.Add(EncryptionECDsaWithSha1);
+			NoParams.Add(EncryptionECDsaWithSha224);
+			NoParams.Add(EncryptionECDsaWithSha256);
+			NoParams.Add(EncryptionECDsaWithSha384);
+			NoParams.Add(EncryptionECDsaWithSha512);
+
+			ECAlgorithms.Add(DigestSha1, EncryptionECDsaWithSha1);
+			ECAlgorithms.Add(DigestSha224, EncryptionECDsaWithSha224);
+			ECAlgorithms.Add(DigestSha256, EncryptionECDsaWithSha256);
+			ECAlgorithms.Add(DigestSha384, EncryptionECDsaWithSha384);
+			ECAlgorithms.Add(DigestSha512, EncryptionECDsaWithSha512);
 		}
 
 		public static string DumpBase64(
@@ -187,13 +187,12 @@ namespace Org.BouncyCastle.Tsp.Tests
 			{
 				if (i + 64 < data.Length)
 				{
-					buf.Append(Encoding.ASCII.GetString(data, i, 64));
+					buf.AppendLine(Encoding.ASCII.GetString(data, i, 64));
 				}
 				else
 				{
-					buf.Append(Encoding.ASCII.GetString(data, i, data.Length - i));
+					buf.AppendLine(Encoding.ASCII.GetString(data, i, data.Length - i));
 				}
-				buf.Append('\n');
 			}
 
 			return buf.ToString();
@@ -201,33 +200,17 @@ namespace Org.BouncyCastle.Tsp.Tests
 
 		public static string GetDigestAlgName(string digestAlgOid)
 		{
-			string algName = (string)digestAlgs[digestAlgOid];
-
-			if (algName != null)
-			{
-				return algName;
-			}
-
-			return digestAlgOid;
+			return CollectionUtilities.GetValueOrKey(DigestAlgs, digestAlgOid);
 		}
 
 		public static string GetEncryptionAlgName(string encryptionAlgOid)
 		{
-			string algName = (string)encryptionAlgs[encryptionAlgOid];
-
-			if (algName != null)
-			{
-				return algName;
-			}
-
-			return encryptionAlgOid;
+			return CollectionUtilities.GetValueOrKey(EncryptionAlgs, encryptionAlgOid);
 		}
 
-		internal static string GetEncOid(
-			AsymmetricKeyParameter key,
-			string digestOID)
+		internal static string GetEncOid(AsymmetricKeyParameter key, string digestOID)
 		{
-			string encOID = null;
+			string encOID;
 
 			if (key is RsaKeyParameters)
 			{
@@ -275,9 +258,7 @@ namespace Org.BouncyCastle.Tsp.Tests
 				else
 				{
 					// TODO Should we insist on algName being one of "EC" or "ECDSA", as Java does?
-					encOID = (string)ecAlgorithms[digestOID];
-
-					if (encOID == null)
+					if (!ECAlgorithms.TryGetValue(digestOID, out encOID))
 						throw new ArgumentException("can't mix ECDSA with anything but SHA family digests");
 				}
 			}
diff --git a/crypto/test/src/util/io/pem/test/AllTests.cs b/crypto/test/src/util/io/pem/test/AllTests.cs
index 9a413450d..88ccf2e40 100644
--- a/crypto/test/src/util/io/pem/test/AllTests.cs
+++ b/crypto/test/src/util/io/pem/test/AllTests.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 using NUnit.Framework;
@@ -14,20 +14,20 @@ namespace Org.BouncyCastle.Utilities.IO.Pem.Tests
 		{
 			for (int i = 1; i != 60; i++)
 			{
-				LengthTest("CERTIFICATE", new ArrayList(), new byte[i]);
+				LengthTest("CERTIFICATE", new List<PemHeader>(), new byte[i]);
 			}
 
-			LengthTest("CERTIFICATE", new ArrayList(), new byte[100]);
-			LengthTest("CERTIFICATE", new ArrayList(), new byte[101]);
-			LengthTest("CERTIFICATE", new ArrayList(), new byte[102]);
-			LengthTest("CERTIFICATE", new ArrayList(), new byte[103]);
+			LengthTest("CERTIFICATE", new List<PemHeader>(), new byte[100]);
+			LengthTest("CERTIFICATE", new List<PemHeader>(), new byte[101]);
+			LengthTest("CERTIFICATE", new List<PemHeader>(), new byte[102]);
+			LengthTest("CERTIFICATE", new List<PemHeader>(), new byte[103]);
 
-			LengthTest("CERTIFICATE", new ArrayList(), new byte[1000]);
-			LengthTest("CERTIFICATE", new ArrayList(), new byte[1001]);
-			LengthTest("CERTIFICATE", new ArrayList(), new byte[1002]);
-			LengthTest("CERTIFICATE", new ArrayList(), new byte[1003]);
+			LengthTest("CERTIFICATE", new List<PemHeader>(), new byte[1000]);
+			LengthTest("CERTIFICATE", new List<PemHeader>(), new byte[1001]);
+			LengthTest("CERTIFICATE", new List<PemHeader>(), new byte[1002]);
+			LengthTest("CERTIFICATE", new List<PemHeader>(), new byte[1003]);
 
-			IList headers = new ArrayList();
+			var headers = new List<PemHeader>();
 			headers.Add(new PemHeader("Proc-Type", "4,ENCRYPTED"));
 			headers.Add(new PemHeader("DEK-Info", "DES3,0001020304050607"));
 			LengthTest("RSA PRIVATE KEY", headers, new byte[103]);
@@ -48,7 +48,7 @@ namespace Org.BouncyCastle.Utilities.IO.Pem.Tests
             }
         }
 
-		private void LengthTest(string type, IList headers, byte[] data)
+		private void LengthTest(string type, IList<PemHeader> headers, byte[] data)
 		{
 			StringWriter sw = new StringWriter();
 			PemWriter pWrt = new PemWriter(sw);
diff --git a/crypto/test/src/util/test/SimpleTest.cs b/crypto/test/src/util/test/SimpleTest.cs
index 1695164e5..91c493ef7 100644
--- a/crypto/test/src/util/test/SimpleTest.cs
+++ b/crypto/test/src/util/test/SimpleTest.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 using System.Reflection;
 
@@ -148,7 +148,7 @@ namespace Org.BouncyCastle.Utilities.Test
 		{
 			string fullPrefix = GetFullName(prefix);
 
-			ArrayList result = new ArrayList();
+			var result = new List<string>();
 			string[] fullNames = GetAssembly().GetManifestResourceNames();
 			foreach (string fullName in fullNames)
 			{
@@ -158,7 +158,7 @@ namespace Org.BouncyCastle.Utilities.Test
 					result.Add(name);
 				}
 			}
-			return (string[])result.ToArray(typeof(string));
+            return result.ToArray();
 		}
 
         private static Assembly GetAssembly()
diff --git a/crypto/test/src/x509/test/TestCertificateGen.cs b/crypto/test/src/x509/test/TestCertificateGen.cs
index d1ac173bc..f4dc5cc01 100644
--- a/crypto/test/src/x509/test/TestCertificateGen.cs
+++ b/crypto/test/src/x509/test/TestCertificateGen.cs
@@ -1,5 +1,4 @@
 using System;
-using System.Collections;
 using System.Collections.Generic;
 
 using NUnit.Framework;