예제 #1
0
        private static PemObject CreatePemObject(object obj, string algorithm, char[] password, SecureRandom random)
        {
            //IL_0008: Unknown result type (might be due to invalid IL or missing references)
            //IL_0016: Unknown result type (might be due to invalid IL or missing references)
            //IL_0024: Unknown result type (might be due to invalid IL or missing references)
            //IL_0032: Unknown result type (might be due to invalid IL or missing references)
            if (obj == null)
            {
                throw new ArgumentNullException("obj");
            }
            if (algorithm == null)
            {
                throw new ArgumentNullException("algorithm");
            }
            if (password == null)
            {
                throw new ArgumentNullException("password");
            }
            if (random == null)
            {
                throw new ArgumentNullException("random");
            }
            if (obj is AsymmetricCipherKeyPair)
            {
                return(CreatePemObject(((AsymmetricCipherKeyPair)obj).Private, algorithm, password, random));
            }
            string text = null;

            byte[] array = null;
            if (obj is AsymmetricKeyParameter)
            {
                AsymmetricKeyParameter asymmetricKeyParameter = (AsymmetricKeyParameter)obj;
                if (asymmetricKeyParameter.IsPrivate)
                {
                    array = EncodePrivateKey(asymmetricKeyParameter, out var keyType);
                    text  = keyType + " PRIVATE KEY";
                }
            }
            if (text == null || array == null)
            {
                throw new PemGenerationException("Object type not supported: " + Platform.GetTypeName(obj));
            }
            string text2 = Platform.ToUpperInvariant(algorithm);

            if (text2 == "DESEDE")
            {
                text2 = "DES-EDE3-CBC";
            }
            int num = (Platform.StartsWith(text2, "AES-") ? 16 : 8);

            byte[] array2 = new byte[num];
            ((Random)random).NextBytes(array2);
            byte[] content = PemUtilities.Crypt(encrypt: true, array, password, text2, array2);
            global::System.Collections.IList list = Platform.CreateArrayList(2);
            list.Add((object)new PemHeader("Proc-Type", "4,ENCRYPTED"));
            list.Add((object)new PemHeader("DEK-Info", text2 + "," + Hex.ToHexString(array2)));
            return(new PemObject(text, list, content));
        }
예제 #2
0
        private static PemObject CreatePemObject(object obj, string algorithm, char[] password, SecureRandom random)
        {
            if (obj == null)
            {
                throw new ArgumentNullException("obj");
            }
            if (algorithm == null)
            {
                throw new ArgumentNullException("algorithm");
            }
            if (password == null)
            {
                throw new ArgumentNullException("password");
            }
            if (random == null)
            {
                throw new ArgumentNullException("random");
            }
            if (obj is AsymmetricCipherKeyPair)
            {
                return(MiscPemGenerator.CreatePemObject(((AsymmetricCipherKeyPair)obj).Private, algorithm, password, random));
            }
            string text = null;

            byte[] array = null;
            if (obj is AsymmetricKeyParameter)
            {
                AsymmetricKeyParameter asymmetricKeyParameter = (AsymmetricKeyParameter)obj;
                if (asymmetricKeyParameter.IsPrivate)
                {
                    string str;
                    array = MiscPemGenerator.EncodePrivateKey(asymmetricKeyParameter, out str);
                    text  = str + " PRIVATE KEY";
                }
            }
            if (text == null || array == null)
            {
                throw new PemGenerationException("Object type not supported: " + obj.GetType().FullName);
            }
            string text2 = Platform.ToUpperInvariant(algorithm);

            if (text2 == "DESEDE")
            {
                text2 = "DES-EDE3-CBC";
            }
            int num = text2.StartsWith("AES-") ? 16 : 8;

            byte[] array2 = new byte[num];
            random.NextBytes(array2);
            byte[] content = PemUtilities.Crypt(true, array, password, text2, array2);
            IList  list    = Platform.CreateArrayList(2);

            list.Add(new PemHeader("Proc-Type", "4,ENCRYPTED"));
            list.Add(new PemHeader("DEK-Info", text2 + "," + Hex.ToHexString(array2)));
            return(new PemObject(text, list, content));
        }
예제 #3
0
//		private string GetHexEncoded(byte[] bytes)
//		{
//			bytes = Hex.Encode(bytes);
//
//			char[] chars = new char[bytes.Length];
//
//			for (int i = 0; i != bytes.Length; i++)
//			{
//				chars[i] = (char)bytes[i];
//			}
//
//			return new string(chars);
//		}

        private PemObject CreatePemObject(
            object obj,
            string algorithm,
            char[]                  password,
            SecureRandom random)
        {
            if (obj == null)
            {
                throw new ArgumentNullException("obj");
            }
            if (algorithm == null)
            {
                throw new ArgumentNullException("algorithm");
            }
            if (password == null)
            {
                throw new ArgumentNullException("password");
            }
            if (random == null)
            {
                throw new ArgumentNullException("random");
            }

            if (obj is AsymmetricCipherKeyPair)
            {
                return(CreatePemObject(((AsymmetricCipherKeyPair)obj).Private, algorithm, password, random));
            }

            string type = null;

            byte[] keyData = null;

            if (obj is AsymmetricKeyParameter)
            {
                IAsymmetricKeyParameter akp = (AsymmetricKeyParameter)obj;
                if (akp.IsPrivate)
                {
                    string keyType;
                    keyData = EncodePrivateKey(akp, out keyType);

                    type = keyType + " PRIVATE KEY";
                }
            }

            if (type == null || keyData == null)
            {
                // TODO Support other types?
                throw new PemGenerationException("Object type not supported: " + obj.GetType().FullName);
            }


            string dekAlgName = Platform.StringToUpper(algorithm);

            // Note: For backward compatibility
            if (dekAlgName == "DESEDE")
            {
                dekAlgName = "DES-EDE3-CBC";
            }

            int ivLength = dekAlgName.StartsWith("AES-") ? 16 : 8;

            byte[] iv = new byte[ivLength];
            random.NextBytes(iv);

            byte[] encData = PemUtilities.Crypt(true, keyData, password, dekAlgName, iv);

            IList headers = Platform.CreateArrayList(2);

            headers.Add(new PemHeader("Proc-Type", "4,ENCRYPTED"));
            headers.Add(new PemHeader("DEK-Info", dekAlgName + "," + Hex.ToHexString(iv)));

            return(new PemObject(type, headers, encData));
        }
예제 #4
0
        private object ReadPrivateKey(PemObject pemObject)
        {
            string text = pemObject.Type.Substring(0, pemObject.Type.Length - "PRIVATE KEY".Length).Trim();

            byte[]      array      = pemObject.Content;
            IDictionary dictionary = Platform.CreateHashtable();

            foreach (PemHeader pemHeader in pemObject.Headers)
            {
                dictionary[pemHeader.Name] = pemHeader.Value;
            }
            string a = (string)dictionary["Proc-Type"];

            if (a == "4,ENCRYPTED")
            {
                if (this.pFinder == null)
                {
                    throw new PasswordException("No password finder specified, but a password is required");
                }
                char[] password = this.pFinder.GetPassword();
                if (password == null)
                {
                    throw new PasswordException("Password is null, but a password is required");
                }
                string   text2  = (string)dictionary["DEK-Info"];
                string[] array2 = text2.Split(new char[]
                {
                    ','
                });
                string dekAlgName = array2[0].Trim();
                byte[] iv         = Hex.Decode(array2[1].Trim());
                array = PemUtilities.Crypt(false, array, password, dekAlgName, iv);
            }
            object result;

            try
            {
                Asn1Sequence instance = Asn1Sequence.GetInstance(array);
                string       a2;
                if ((a2 = text) != null)
                {
                    AsymmetricKeyParameter asymmetricKeyParameter;
                    AsymmetricKeyParameter publicParameter;
                    if (!(a2 == "RSA"))
                    {
                        if (!(a2 == "DSA"))
                        {
                            if (!(a2 == "EC"))
                            {
                                if (!(a2 == "ENCRYPTED"))
                                {
                                    if (!(a2 == ""))
                                    {
                                        goto IL_356;
                                    }
                                    result = PrivateKeyFactory.CreateKey(PrivateKeyInfo.GetInstance(instance));
                                    return(result);
                                }
                                else
                                {
                                    char[] password2 = this.pFinder.GetPassword();
                                    if (password2 == null)
                                    {
                                        throw new PasswordException("Password is null, but a password is required");
                                    }
                                    result = PrivateKeyFactory.DecryptKey(password2, EncryptedPrivateKeyInfo.GetInstance(instance));
                                    return(result);
                                }
                            }
                            else
                            {
                                ECPrivateKeyStructure eCPrivateKeyStructure = new ECPrivateKeyStructure(instance);
                                AlgorithmIdentifier   algID   = new AlgorithmIdentifier(X9ObjectIdentifiers.IdECPublicKey, eCPrivateKeyStructure.GetParameters());
                                PrivateKeyInfo        keyInfo = new PrivateKeyInfo(algID, eCPrivateKeyStructure.ToAsn1Object());
                                asymmetricKeyParameter = PrivateKeyFactory.CreateKey(keyInfo);
                                DerBitString publicKey = eCPrivateKeyStructure.GetPublicKey();
                                if (publicKey != null)
                                {
                                    SubjectPublicKeyInfo keyInfo2 = new SubjectPublicKeyInfo(algID, publicKey.GetBytes());
                                    publicParameter = PublicKeyFactory.CreateKey(keyInfo2);
                                }
                                else
                                {
                                    publicParameter = ECKeyPairGenerator.GetCorrespondingPublicKey((ECPrivateKeyParameters)asymmetricKeyParameter);
                                }
                            }
                        }
                        else
                        {
                            if (instance.Count != 6)
                            {
                                throw new PemException("malformed sequence in DSA private key");
                            }
                            DerInteger    derInteger  = (DerInteger)instance[1];
                            DerInteger    derInteger2 = (DerInteger)instance[2];
                            DerInteger    derInteger3 = (DerInteger)instance[3];
                            DerInteger    derInteger4 = (DerInteger)instance[4];
                            DerInteger    derInteger5 = (DerInteger)instance[5];
                            DsaParameters parameters  = new DsaParameters(derInteger.Value, derInteger2.Value, derInteger3.Value);
                            asymmetricKeyParameter = new DsaPrivateKeyParameters(derInteger5.Value, parameters);
                            publicParameter        = new DsaPublicKeyParameters(derInteger4.Value, parameters);
                        }
                    }
                    else
                    {
                        if (instance.Count != 9)
                        {
                            throw new PemException("malformed sequence in RSA private key");
                        }
                        RsaPrivateKeyStructure instance2 = RsaPrivateKeyStructure.GetInstance(instance);
                        publicParameter        = new RsaKeyParameters(false, instance2.Modulus, instance2.PublicExponent);
                        asymmetricKeyParameter = new RsaPrivateCrtKeyParameters(instance2.Modulus, instance2.PublicExponent, instance2.PrivateExponent, instance2.Prime1, instance2.Prime2, instance2.Exponent1, instance2.Exponent2, instance2.Coefficient);
                    }
                    result = new AsymmetricCipherKeyPair(publicParameter, asymmetricKeyParameter);
                    return(result);
                }
IL_356:
                throw new ArgumentException("Unknown key type: " + text, "type");
            }
            catch (IOException ex)
            {
                throw ex;
            }
            catch (Exception ex2)
            {
                throw new PemException("problem creating " + text + " private key: " + ex2.ToString());
            }
            return(result);
        }
예제 #5
0
        public void WriteObject(
            object obj,
            string algorithm,
            char[]                  password,
            SecureRandom random)
        {
            if (obj == null)
            {
                throw new ArgumentNullException("obj");
            }
            if (algorithm == null)
            {
                throw new ArgumentNullException("algorithm");
            }
            if (password == null)
            {
                throw new ArgumentNullException("password");
            }
            if (random == null)
            {
                throw new ArgumentNullException("random");
            }

            if (obj is AsymmetricCipherKeyPair)
            {
                WriteObject(((AsymmetricCipherKeyPair)obj).Private, algorithm, password, random);
                return;
            }

            string type = null;

            byte[] keyData = null;

            if (obj is AsymmetricKeyParameter)
            {
                AsymmetricKeyParameter akp = (AsymmetricKeyParameter)obj;
                if (akp.IsPrivate)
                {
                    string keyType;
                    keyData = EncodePrivateKey(akp, out keyType);

                    type = keyType + " PRIVATE KEY";
                }
            }

            if (type == null || keyData == null)
            {
                // TODO Support other types?
                throw new ArgumentException("Object type not supported: " + obj.GetType().FullName, "obj");
            }


            string dekAlgName = algorithm.ToUpper(CultureInfo.InvariantCulture);

            // Note: For backward compatibility
            if (dekAlgName == "DESEDE")
            {
                dekAlgName = "DES-EDE3-CBC";
            }

            int ivLength = dekAlgName.StartsWith("AES-") ? 16 : 8;

            byte[] iv = new byte[ivLength];
            random.NextBytes(iv);

            byte[] encData = PemUtilities.Crypt(true, keyData, password, dekAlgName, iv);
            byte[] hexIV   = Hex.Encode(iv);

            WritePemBlock(type, encData,
                          "Proc-Type: 4,ENCRYPTED",
                          "DEK-Info: " + dekAlgName + "," + Encoding.ASCII.GetString(hexIV, 0, hexIV.Length));
        }
예제 #6
0
        /**
         * Read a Key Pair
         */
        private object ReadPrivateKey(PemObject pemObject)
        {
            //
            // extract the key
            //
            Debug.Assert(Platform.EndsWith(pemObject.Type, "PRIVATE KEY"));

            string type = pemObject.Type.Substring(0, pemObject.Type.Length - "PRIVATE KEY".Length).Trim();

            byte[] keyBytes = pemObject.Content;

            IDictionary fields = Platform.CreateHashtable();

            foreach (PemHeader header in pemObject.Headers)
            {
                fields[header.Name] = header.Value;
            }

            string procType = (string)fields["Proc-Type"];

            if (procType == "4,ENCRYPTED")
            {
                if (pFinder == null)
                {
                    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"];
                string[] tknz    = dekInfo.Split(',');

                string dekAlgName = tknz[0].Trim();
                byte[] iv         = Hex.Decode(tknz[1].Trim());

                keyBytes = PemUtilities.Crypt(false, keyBytes, password, dekAlgName, iv);
            }

            try
            {
                AsymmetricKeyParameter pubSpec, privSpec;
                Asn1Sequence           seq = Asn1Sequence.GetInstance(keyBytes);

                switch (type)
                {
                case "RSA":
                {
                    if (seq.Count != 9)
                    {
                        throw new PemException("malformed sequence in RSA private key");
                    }

                    RsaPrivateKeyStructure rsa = RsaPrivateKeyStructure.GetInstance(seq);

                    pubSpec  = new RsaKeyParameters(false, rsa.Modulus, rsa.PublicExponent);
                    privSpec = new RsaPrivateCrtKeyParameters(
                        rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent,
                        rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2,
                        rsa.Coefficient);

                    break;
                }

                case "DSA":
                {
                    if (seq.Count != 6)
                    {
                        throw new PemException("malformed sequence in DSA private key");
                    }

                    // TODO Create an ASN1 object somewhere for this?
                    //DerInteger v = (DerInteger)seq[0];
                    DerInteger p = (DerInteger)seq[1];
                    DerInteger q = (DerInteger)seq[2];
                    DerInteger g = (DerInteger)seq[3];
                    DerInteger y = (DerInteger)seq[4];
                    DerInteger x = (DerInteger)seq[5];

                    DsaParameters parameters = new DsaParameters(p.Value, q.Value, g.Value);

                    privSpec = new DsaPrivateKeyParameters(x.Value, parameters);
                    pubSpec  = new DsaPublicKeyParameters(y.Value, parameters);

                    break;
                }

                case "EC":
                {
                    ECPrivateKeyStructure pKey  = ECPrivateKeyStructure.GetInstance(seq);
                    AlgorithmIdentifier   algId = new AlgorithmIdentifier(
                        X9ObjectIdentifiers.IdECPublicKey, pKey.GetParameters());

                    PrivateKeyInfo privInfo = new PrivateKeyInfo(algId, pKey.ToAsn1Object());

                    // TODO Are the keys returned here ECDSA, as Java version forces?
                    privSpec = PrivateKeyFactory.CreateKey(privInfo);

                    DerBitString pubKey = pKey.GetPublicKey();
                    if (pubKey != null)
                    {
                        SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo(algId, pubKey.GetBytes());

                        // TODO Are the keys returned here ECDSA, as Java version forces?
                        pubSpec = PublicKeyFactory.CreateKey(pubInfo);
                    }
                    else
                    {
                        pubSpec = ECKeyPairGenerator.GetCorrespondingPublicKey(
                            (ECPrivateKeyParameters)privSpec);
                    }

                    break;
                }

                case "ENCRYPTED":
                {
                    char[] password = pFinder.GetPassword();

                    if (password == null)
                    {
                        throw new PasswordException("Password is null, but a password is required");
                    }

                    return(PrivateKeyFactory.DecryptKey(password, EncryptedPrivateKeyInfo.GetInstance(seq)));
                }

                case "":
                {
                    return(PrivateKeyFactory.CreateKey(PrivateKeyInfo.GetInstance(seq)));
                }

                default:
                    throw new ArgumentException("Unknown key type: " + type, "type");
                }

                return(new AsymmetricCipherKeyPair(pubSpec, privSpec));
            }
            catch (IOException e)
            {
                throw e;
            }
            catch (Exception e)
            {
                throw new PemException(
                          "problem creating " + type + " private key: " + e.ToString());
            }
        }
        /**
         * Read a Key Pair
         */
        private AsymmetricCipherKeyPair ReadKeyPair(
            string type,
            string endMarker)
        {
            //
            // extract the key
            //
            IDictionary fields = new Hashtable();

            byte[] keyBytes = ReadBytesAndFields(endMarker, fields);

            string procType = (string)fields["Proc-Type"];

            if (procType == "4,ENCRYPTED")
            {
                if (pFinder == null)
                {
                    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"];
                string[] tknz    = dekInfo.Split(',');

                string dekAlgName = tknz[0].Trim();
                byte[] iv         = Hex.Decode(tknz[1].Trim());

                keyBytes = PemUtilities.Crypt(false, keyBytes, password, dekAlgName, iv);
            }

            try
            {
                AsymmetricKeyParameter pubSpec, privSpec;
                Asn1Sequence           seq = (Asn1Sequence)Asn1Object.FromByteArray(keyBytes);

                switch (type)
                {
                case "RSA":
                {
                    RsaPrivateKeyStructure rsa = new RsaPrivateKeyStructure(seq);

                    pubSpec  = new RsaKeyParameters(false, rsa.Modulus, rsa.PublicExponent);
                    privSpec = new RsaPrivateCrtKeyParameters(
                        rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent,
                        rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2,
                        rsa.Coefficient);

                    break;
                }

                case "DSA":
                {
                    // TODO Create an ASN1 object somewhere for this?
                    //DerInteger v = (DerInteger)seq[0];
                    DerInteger p = (DerInteger)seq[1];
                    DerInteger q = (DerInteger)seq[2];
                    DerInteger g = (DerInteger)seq[3];
                    DerInteger y = (DerInteger)seq[4];
                    DerInteger x = (DerInteger)seq[5];

                    DsaParameters parameters = new DsaParameters(p.Value, q.Value, g.Value);

                    privSpec = new DsaPrivateKeyParameters(x.Value, parameters);
                    pubSpec  = new DsaPublicKeyParameters(y.Value, parameters);

                    break;
                }

                default:
                    throw new ArgumentException("Unknown key type: " + type, "type");
                }

                return(new AsymmetricCipherKeyPair(pubSpec, privSpec));
            }
            catch (Exception e)
            {
                throw new PemException(
                          "problem creating " + type + " private key: " + e.ToString());
            }
        }
예제 #8
0
        internal static byte[] Crypt(bool encrypt, byte[] bytes, char[] password, string dekAlgName, byte[] iv)
        {
            PemUtilities.PemBaseAlg baseAlg;
            PemUtilities.PemMode    pemMode;
            PemUtilities.ParseDekAlgName(dekAlgName, out baseAlg, out pemMode);
            string text;

            switch (pemMode)
            {
            case PemUtilities.PemMode.CBC:
            case PemUtilities.PemMode.ECB:
                text = "PKCS5Padding";
                break;

            case PemUtilities.PemMode.CFB:
            case PemUtilities.PemMode.OFB:
                text = "NoPadding";
                break;

            default:
                throw new EncryptionException("Unknown DEK algorithm: " + dekAlgName);
            }
            byte[] array = iv;
            string text2;

            switch (baseAlg)
            {
            case PemUtilities.PemBaseAlg.AES_128:
            case PemUtilities.PemBaseAlg.AES_192:
            case PemUtilities.PemBaseAlg.AES_256:
                text2 = "AES";
                if (array.Length > 8)
                {
                    array = new byte[8];
                    Array.Copy(iv, 0, array, 0, array.Length);
                }
                break;

            case PemUtilities.PemBaseAlg.BF:
                text2 = "BLOWFISH";
                break;

            case PemUtilities.PemBaseAlg.DES:
                text2 = "DES";
                break;

            case PemUtilities.PemBaseAlg.DES_EDE:
            case PemUtilities.PemBaseAlg.DES_EDE3:
                text2 = "DESede";
                break;

            case PemUtilities.PemBaseAlg.RC2:
            case PemUtilities.PemBaseAlg.RC2_40:
            case PemUtilities.PemBaseAlg.RC2_64:
                text2 = "RC2";
                break;

            default:
                throw new EncryptionException("Unknown DEK algorithm: " + dekAlgName);
            }
            string algorithm = string.Concat(new object[]
            {
                text2,
                "/",
                pemMode,
                "/",
                text
            });
            IBufferedCipher   cipher     = CipherUtilities.GetCipher(algorithm);
            ICipherParameters parameters = PemUtilities.GetCipherParameters(password, baseAlg, array);

            if (pemMode != PemUtilities.PemMode.ECB)
            {
                parameters = new ParametersWithIV(parameters, iv);
            }
            cipher.Init(encrypt, parameters);
            return(cipher.DoFinal(bytes));
        }