Esempio n. 1
0
        /// <summary>
        /// To be called after the TPM has returned the addedTo part of the certificate and the signature.  Assembles
        /// partialCert, addedTo, and the signature to form  an actual X.509 certificate encapsulated in a Bouncy Castle
        /// X509Certificate
        /// </summary>
        /// <param name="partialCert"></param>
        /// <param name="addedToCertificate"></param>
        /// <param name="signature"></param>
        /// <returns></returns>
        internal static X509Certificate AssembleCertificate(
            PartialCertificate partialCert, AddedToCertificate addedToCertificate,
            byte[] signatureBytes)
        {
            Debug.Assert(addedToCertificate.Version.ToString() == "2");
            var signature = new DerBitString(signatureBytes);
            var sigAlgID  = partialCert.SigAlgID ?? addedToCertificate.SigAlgID;

            // Assemble TBS.  Start with a vector which we will later convert to a sequence
            Asn1EncodableVector tbsContents = new Asn1EncodableVector();

            tbsContents.Add(new DerTaggedObject(0, new DerInteger(BigInteger.ValueOf(2))));
            tbsContents.Add(addedToCertificate.SerialNumber);
            tbsContents.Add(sigAlgID);
            tbsContents.Add(partialCert.Issuer);
            tbsContents.Add(new CertificateValidity(partialCert.NotBefore, partialCert.NotAfter));
            tbsContents.Add(partialCert.Subject);
            tbsContents.Add(addedToCertificate.SubjectPublicKeyInfo);
            // Add optional components
            if (partialCert.IssuerUniqueId != null)
            {
                tbsContents.Add(new DerTaggedObject(false, 1, new DerBitString(partialCert.IssuerUniqueId)));
            }
            if (partialCert.SubjectUniqueId != null)
            {
                tbsContents.Add(new DerTaggedObject(false, 2, new DerBitString(partialCert.SubjectUniqueId)));
            }
            if (partialCert.Extensions != null)
            {
                tbsContents.Add(new DerTaggedObject(3, partialCert.Extensions.ToAsn1Object()));
            }

            // Convert the vector to an ASN SEQUENCE
            var tbsCertificate = new DerSequence(tbsContents);

            // assemble the certificate.  Start with the components as a vector
            Asn1EncodableVector certContents = new Asn1EncodableVector();

            certContents.Add(tbsCertificate);
            certContents.Add(sigAlgID);
            certContents.Add(signature);

            // Convert to a SEQUENCE.  certSequence will contain the DER encoded certificate
            var certSequence = new DerSequence(certContents);

            // Convert to a first-class BC X509Certificate
            var certBytes = certSequence.GetEncoded();
            var cert      = new X509CertificateParser().ReadCertificate(certSequence.GetEncoded());

            // and return it
            return(cert);
        }
Esempio n. 2
0
        public static byte[] encodeSM2CipherToDER(byte[] cipher)
        {
            int startPos = 1;

            int curveLength  = 32;
            int digestLength = 32;

            byte[] c1x = new byte[curveLength];
            Buffer.BlockCopy(cipher, startPos, c1x, 0, c1x.Length);
            startPos += c1x.Length;

            byte[] c1y = new byte[curveLength];
            Buffer.BlockCopy(cipher, startPos, c1y, 0, c1y.Length);
            startPos += c1y.Length;

            byte[] c2 = new byte[cipher.Length - c1x.Length - c1y.Length - 1 - digestLength];
            Buffer.BlockCopy(cipher, startPos, c2, 0, c2.Length);
            startPos += c2.Length;

            byte[] c3 = new byte[digestLength];
            Buffer.BlockCopy(cipher, startPos, c3, 0, c3.Length);

            Asn1Encodable[] arr = new Asn1Encodable[4];
            arr[0] = new DerInteger(new BigInteger(1, c1x)); //
            arr[1] = new DerInteger(new BigInteger(1, c1y)); //
            arr[2] = new DerOctetString(c3);
            arr[3] = new DerOctetString(c2);
            DerSequence ds = new DerSequence(arr);

            return(ds.GetEncoded(Asn1Encodable.Der));
        }
Esempio n. 3
0
        /// <summary>
        /// SM2签名Hard转soft
        /// </summary>
        /// <param name="hardSign"></param>
        /// <returns></returns>
        public static String SM2SignHardToSoft(String hardSign)
        {
            byte[] bytes = hardSign.hexToByte();
            byte[] r     = new byte[bytes.Length / 2];
            byte[] s     = new byte[bytes.Length / 2];
            System.Array.Copy(bytes, 0, r, 0, bytes.Length / 2);
            System.Array.Copy(bytes, bytes.Length / 2, s, 0, bytes.Length / 2);
            var d_r = new DerInteger(SM2CryptoServiceProvider.byteConvertInteger(r));
            var d_s = new DerInteger(SM2CryptoServiceProvider.byteConvertInteger(s));
            var v2  = new Asn1EncodableVector();

            v2.Add(d_r);
            v2.Add(d_s);
            var sign = new DerSequence(v2);

            String result = null;

            try
            {
                result = sign.GetEncoded().ByteArrayToHex();
            }
            catch (IOException e)
            {
                //e.printStackTrace();
                throw (e);
            }
            //SM2加密机转软加密编码格式
            //return SM2SignHardKeyHead+hardSign.substring(0, hardSign.Length()/2)+SM2SignHardKeyMid+hardSign.substring(hardSign.Length()/2);
            return(result);
        }
Esempio n. 4
0
        private string GenerateX509Cert(string publicKey, string x509Subject)
        {
            Asn1Sequence asn1Sequence = null;

            using (var reader = new StringReader(publicKey))
            {
                // Read the RSA public key from the input string.
                var pemReader = new PemReader(reader);
                var pemObject = pemReader.ReadPemObject();
                asn1Sequence = (Asn1Sequence)Asn1Object.FromByteArray(pemObject.Content);
            }

            // Generate a TBS certificate. We use placeholder-like values since
            // the consumer of this certificate should only use the subject
            // public key info.
            var tbsCertGen = new V3TbsCertificateGenerator();

            tbsCertGen.SetSerialNumber(new DerInteger(1));
            var signatureAlgId = new AlgorithmIdentifier(PkcsObjectIdentifiers.Sha1WithRsaEncryption, DerNull.Instance);

            tbsCertGen.SetSignature(signatureAlgId);
            tbsCertGen.SetIssuer(new X509Name("CN=Root Agency"));
            var dateTimeNow = DateTime.Now;

            tbsCertGen.SetStartDate(new Time(dateTimeNow.AddMinutes(-10)));
            tbsCertGen.SetEndDate(new Time(dateTimeNow.AddYears(1)));   // Openssh key doesn`t have any start/end date, this is to satisfy RDFE
            tbsCertGen.SetSubject(new X509Name(x509Subject));
            tbsCertGen.SetSubjectPublicKeyInfo(new SubjectPublicKeyInfo(new AlgorithmIdentifier(PkcsObjectIdentifiers.RsaEncryption, DerNull.Instance), asn1Sequence));
            var tbsCert = tbsCertGen.GenerateTbsCertificate();

            // Per RFC 3280, the layout of an X.509 v3 certificate looks like:
            // Certificate  ::=  SEQUENCE  {
            //     tbsCertificate       TBSCertificate,
            //     signatureAlgorithm   AlgorithmIdentifier,
            //     signatureValue       BIT STRING
            // }
            // Since we don't have access to the private key, we cannot create
            // a signature for the TBS. However, a valid certificate requires
            // a bit string for the signature value, so we use a 0-byte array
            // in its place.
            Asn1EncodableVector v = new Asn1EncodableVector();

            v.Add(tbsCert);
            v.Add(signatureAlgId);
            v.Add(new DerBitString(new byte[0]));
            var derSequence = new DerSequence(v);

            // Output the DER-encoded X509 certificate.
            var sb = new StringBuilder();

            using (var writer = new StringWriter(sb, CultureInfo.InvariantCulture))
            {
                var pemWriter = new PemWriter(writer);
                pemWriter.WriteObject(new PemObject("CERTIFICATE", derSequence.GetEncoded()));
            }

            return(sb.ToString());
        }
Esempio n. 5
0
        private string GeneratePkcs1PublicKeyFromRsaEncryptedOpenSshPublicKey(string content)
        {
            List <byte[]> data = this.GetOpenSshPublicKeyInBinary(content);

            if (data.Count != 3)
            {
                throw new InvalidOperationException("Given OpenSSH key body is invalid.");
            }

            //// RFC 3447 (PKCS #1)
            //// 3.1 RSA public key
            //// For the purposes of this document, an RSA public key consists of two
            //// components:

            ////      n        the RSA modulus, a positive integer
            ////      e        the RSA public exponent, a positive integer

            //// A recommended syntax for interchanging RSA public keys between
            //// implementations is given in Appendix A.1.1; an implementation's
            //// internal representation may differ.

            //// A.1.1 RSA public key syntax
            //// An RSA public key should be represented with the ASN.1 type
            //// RSAPublicKey:
            ////   RSAPublicKey ::= SEQUENCE {
            ////       modulus           INTEGER,  -- n
            ////       publicExponent    INTEGER   -- e
            ////   }
            //// The fields of type RSAPublicKey have the following meanings:
            ////      * modulus is the RSA modulus n.
            ////      * publicExponent is the RSA public exponent e.

            //// RFC 4251: Strings are also used to store text.  In that case, US-ASCII is
            ////           used for internal names, and ISO-10646 UTF-8 for text that might be displayed to the user.
            string algorithmName = Encoding.UTF8.GetString(data[0]);

            if (!"ssh-rsa".Equals(algorithmName, StringComparison.Ordinal))
            {
                throw new InvalidOperationException("Invalid OpenSSH key body, expected 'ssh-rsa' encrypted.");
            }

            var publicExponent = new DerInteger(data[1]);
            var modulus        = new DerInteger(data[2]);
            var sequence       = new DerSequence(new Asn1Encodable[] { modulus, publicExponent });

            // Generate DER-encoded public key
            StringBuilder sb = new StringBuilder();

            using (var sw = new StringWriter(sb, CultureInfo.InvariantCulture))
            {
                var pemWriter = new Org.BouncyCastle.Utilities.IO.Pem.PemWriter(sw);
                pemWriter.WriteObject(new PemObject("RSA PUBLIC KEY", sequence.GetEncoded()));
            }

            return(sb.ToString());
        }
Esempio n. 6
0
        private static byte[] EncodePublicKey(PublicKey publicKey)
        {
            var rawKey = publicKey.EncodedKeyValue.RawData;

            var sequence = new DerSequence(
                new DerSequence(new DerObjectIdentifier(publicKey.Oid.Value), DerNull.Instance),
                new DerBitString(rawKey)
                );

            return(sequence.GetEncoded());
        }
Esempio n. 7
0
File: asn1.cs Progetto: AS2805/6.5.3
        public byte[] SHA256_DER(byte[] message)
        {
            Asn1EncodableVector v = new Asn1EncodableVector();

            v.Add(new DerObjectIdentifier("2.16.840.1.101.3.4.2.1"));
            v.Add(new DerOctetString(message));
            var s = new DerSequence(v);

            DumpASN(s);
            return(s.GetEncoded());
        }
Esempio n. 8
0
File: asn1.cs Progetto: AS2805/6.5.3
        public byte[] KI_KeyBlock(byte[] KI, byte[] TCUID, byte[] DTS, byte[] RNsp, byte[] user_data)
        {
            Asn1EncodableVector v = new Asn1EncodableVector();

            v.Add(new DerOctetString(KI));
            v.Add(new DerOctetString(TCUID));
            v.Add(new DerOctetString(DTS));
            v.Add(new DerOctetString(RNsp));
            v.Add(new DerOctetString(user_data));
            var s = new DerSequence(v);

            DumpASN(s);
            return(s.GetEncoded());
        }
Esempio n. 9
0
        /**
         * 私钥签名
         * 使用SM3进行对明文数据计算一个摘要值
         * @param privatekey 私钥
         * @param sourceData 明文数据
         * @return 签名后的值
         * @throws Exception
         */
        public static SM2SignVO Sign2SM2(byte[] privatekey, byte[] sourceData)
        {
            SM2SignVO sm2SignVO = new SM2SignVO();

            sm2SignVO.setSm2_type("sign");
            var        factory = SM2CryptoServiceProvider.Instance;
            BigInteger userD   = new BigInteger(privatekey);

            //System.out.println("userD:"+userD.toString(16));
            sm2SignVO.setSm2_userd(userD.ToByteArray().ToHexString());

            ECPoint userKey = factory.ecc_point_g.Multiply(userD);
            //System.out.println("椭圆曲线点X: "+ userKey.getXCoord().toBigInteger().toString(16));
            //System.out.println("椭圆曲线点Y: "+ userKey.getYCoord().toBigInteger().toString(16));

            SM3Digest sm3Digest = new SM3Digest();

            byte[] z = factory.Sm2GetZ(USER_ID.GetBytes(), userKey);
            //System.out.println("SM3摘要Z: " + Util.getHexString(z));
            //System.out.println("被加密数据的16进制: " + Util.getHexString(sourceData));
            sm2SignVO.setSm3_z(z.ToHexString());
            sm2SignVO.setSign_express(sourceData.ToHexString());

            sm3Digest.update(z, 0, z.Length);
            sm3Digest.update(sourceData, 0, sourceData.Length);
            byte[] md = new byte[32];
            sm3Digest.doFinal(md, 0);
            //System.out.println("SM3摘要值: " + Util.getHexString(md));
            sm2SignVO.setSm3_digest(md.ToHexString());

            SM2Result sm2Result = new SM2Result();

            factory.sm2Sign(md, userD, userKey, sm2Result);
            //System.out.println("r: " + sm2Result.r.toString(16));
            //System.out.println("s: " + sm2Result.s.toString(16));
            sm2SignVO.setSign_r(sm2Result.r.ToByteArray().ToHexString());
            sm2SignVO.setSign_s(sm2Result.s.ToByteArray().ToHexString());

            var d_r = new DerInteger(sm2Result.r);
            var d_s = new DerInteger(sm2Result.s);
            var v2  = new Asn1EncodableVector();

            v2.Add(d_r);
            v2.Add(d_s);
            var    sign   = new DerSequence(v2);
            String result = sign.GetEncoded().ByteArrayToHex();

            sm2SignVO.setSm2_sign(result);
            return(sm2SignVO);
        }
        /// <summary>
        /// Returns the extension in raw data
        /// </summary>
        /// <returns></returns>
        public byte[] Export()
        {
            if (string.IsNullOrEmpty(CertificateTemplate))
            {
                throw new ArgumentException();
            }

            var param = new List <Asn1Encodable>();

            param.Add(new DerBmpString(CertificateTemplate));

            var seq = new DerSequence(param.ToArray());

            return(seq.GetEncoded());
        }
Esempio n. 11
0
        private static byte[] BuildOCSPResponse(byte[] BasicOCSPResponse)
        {
            DerOctetString      doctet = new DerOctetString(BasicOCSPResponse);
            Asn1EncodableVector v2     = new Asn1EncodableVector();

            v2.Add(OcspObjectIdentifiers.PkixOcspBasic);
            v2.Add(doctet);
            DerEnumerated       den = new DerEnumerated(0);
            Asn1EncodableVector v3  = new Asn1EncodableVector();

            v3.Add(den);
            v3.Add(new DerTaggedObject(true, 0, new DerSequence(v2)));
            DerSequence seq = new DerSequence(v3);

            return(seq.GetEncoded());
        }
Esempio n. 12
0
        public String getEncoded()
        {
            //TextWriter textWriter = new StringWriter();
            //PemWriter pemWriter = new PemWriter(textWriter);
            //pemWriter.WriteObject(pubKey);
            //pemWriter.Writer.Flush();
            //String pemString = textWriter.ToString();

            // I am forced to use this type of PEM coding, although I am not sure if it is right.
            // The previous code from Bouncy Castle, although technicaly correct, doesn't output the same coding od Dart code.
            DerSequence pubKeySequence = new DerSequence(new DerInteger(pubKey.Modulus), new DerInteger(pubKey.Exponent));
            string      dataBase64     = Convert.ToBase64String(pubKeySequence.GetEncoded());
            string      pemString      = $"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A{dataBase64}\n-----END PUBLIC KEY-----";

            return(pemString);
            //*** 20200524 RC: Encoding to be checked against rel. 2.1 Dart!
        }
        /// <summary>
        /// Returns the extension in raw data
        /// </summary>
        /// <returns></returns>
        public byte[] Export()
        {
            if (Id == null)
            {
                throw new ArgumentException();
            }

            var param = new List <Asn1Encodable>();

            param.Add(new DerObjectIdentifier(Id.Value));
            param.Add(new DerInteger(MajorVersion));
            param.Add(new DerInteger(MinorVersion));

            var seq = new DerSequence(param.ToArray());

            return(seq.GetEncoded());
        }
Esempio n. 14
0
        public void TestFormatSignature()
        {
            var random  = new Random();
            var dsa_key = new SshKey(SshVersion.SSH2, new DsaPublicKeyParameters(
                                         new BigInteger("1"),
                                         new DsaParameters(new BigInteger("2"), new BigInteger("3"),
                                                           new BigInteger("4"))));

            // test that dsa signature works when values are not full 20 bytes.
            byte[] r_bytes = new byte[19];
            byte[] s_bytes = new byte[19];
            random.NextBytes(r_bytes);
            random.NextBytes(s_bytes);
            var r         = new DerInteger(r_bytes);
            var s         = new DerInteger(s_bytes);
            var sequence  = new DerSequence(r, s);
            var signature = dsa_key.FormatSignature(sequence.GetEncoded());

            Assert.That(signature.Count(), Is.EqualTo(40));
        }
Esempio n. 15
0
        public static bool verifySign(string signature, byte[] origdata, ICipherParameters pubkey)
        {
            var dsa = SignerUtilities.GetSigner(ECDSA);

            dsa.Init(false, pubkey);
            dsa.BlockUpdate(origdata, 0, origdata.Length);

            BigInteger          r   = new BigInteger(signature.Substring(0, 64), 16);
            BigInteger          s   = new BigInteger(signature.Substring(64, 64), 16);
            Asn1EncodableVector vec = new Asn1EncodableVector();

            vec.Add(new DerInteger(r));
            vec.Add(new DerInteger(s));
            Asn1Sequence seq = new DerSequence(vec);

            byte[] sign   = seq.GetEncoded();
            bool   result = dsa.VerifySignature(sign);

            return(result);
        }
        /// <summary>
        /// Signature
        /// </summary>
        /// <param name="data"></param>
        /// <param name="userId"></param>
        /// <param name="publicKey"></param>
        /// <returns></returns>
        public static byte[] Signature2(byte[] data, byte[] userId, byte[] publicKey)
        {
            if (publicKey is null || publicKey.Length == 0)
            {
                return(null);
            }

            if (data is null || data.Length == 0)
            {
                return(null);
            }

            SM2Core    sm2     = SM2Core.Instance;
            BigInteger userD   = new BigInteger(Hex.Decode(publicKey));
            ECPoint    userKey = sm2.ecc_point_g.Multiply(userD);

            SM2Core.SM2_SM3Digest sm3 = new SM2Core.SM2_SM3Digest();
            byte[] z = sm2.Sm2GetZ(userId, userKey);

            sm3.BlockUpdate(z, 0, z.Length);
            sm3.BlockUpdate(data, 0, data.Length);
            byte[] md = new byte[32];
            sm3.DoFinal(md, 0);

            SM2Result sm2Result = new SM2Result();

            sm2.Sm2Sign(md, userD, userKey, sm2Result);

            DerInteger          d_r = new DerInteger(sm2Result.r);
            DerInteger          d_s = new DerInteger(sm2Result.s);
            Asn1EncodableVector v2  = new Asn1EncodableVector();

            v2.Add(d_r);
            v2.Add(d_s);
            DerSequence sign = new DerSequence(v2);

            byte[] signdata = sign.GetEncoded();
            return(signdata);
        }
Esempio n. 17
0
        private byte[] SignBytesDsa(byte[] byteArray, string pathToPrivateKeyPemFile)
        {
            // Create a digest of nonce + cnonce
            // This only seems to work with SHA1 (SHA256 gives us a 401 error)
            var sha    = SHA1.Create();
            var digest = sha.ComputeHash(byteArray);

            // Read DSA key
            DsaKeyParameters keyParameters;

            using (var fileStream = System.IO.File.OpenText(pathToPrivateKeyPemFile))
            {
                var pemReader = new PemReader(fileStream);
                keyParameters = (DsaKeyParameters)pemReader.ReadObject();
            }

            // Create DSA signer
            DsaSigner sig = new DsaSigner();

            sig.Init(true, keyParameters);

            // Digitally sign the digest with our private key
            // The corresponding public key is in our admin handle on the server
            var signature = sig.GenerateSignature(digest);

            // Signature bytes from a DSA key need to be DER-encoded
            // This signature is in two parts (r and s)
            DerSequence seq = new DerSequence(new Asn1Encodable[2] {
                new DerInteger(signature[0]), new DerInteger(signature[1])
            });
            var encode    = seq.GetEncoded();
            var derEncode = seq.GetDerEncoded();


            return(seq.GetDerEncoded());
        }
Esempio n. 18
0
        /// <summary>
        /// Write myself to the given stream
        /// </summary>
        public void WriteTo(Stream stream, out string md5FingerPrint, out string sha1FingerPrint)
        {
            X509Certificate[]  cert;
            AsymmetricKeyEntry privateKey;

            LoadPfx(out cert, out privateKey);

            var certsVector = new Asn1EncodableVector();

            md5FingerPrint  = null;
            sha1FingerPrint = null;
            foreach (var c in cert)
            {
                var certStream = new MemoryStream(c.GetEncoded());
                var certStruct = X509CertificateStructure.GetInstance(new Asn1InputStream(certStream).ReadObject());
                certsVector.Add(certStruct);

                if (md5FingerPrint == null)
                {
                    var certData = certStream.ToArray();
                    md5FingerPrint = CreateFingerprint(new MD5Digest(), certData);
                }

                if (sha1FingerPrint == null)
                {
                    var certData = certStream.ToArray();
                    sha1FingerPrint = CreateFingerprint(new Sha1Digest(), certData);
                }
            }

            var encryptedSignature = GetSignature(signature, privateKey.Key);
            var signerInfo         = new SignerInfo(
                new DerInteger(1),
                new IssuerAndSerialNumber(cert[0].IssuerDN, cert[0].SerialNumber),
                new AlgorithmIdentifier(Oids.SHA1, DerNull.Instance),
                null,
                new AlgorithmIdentifier(Oids.RSA, DerNull.Instance),
                new DerOctetString(encryptedSignature),
                null);

            var pkcs7 = new SignedData(
                new DerInteger(1),
                new DerSet(new AlgorithmIdentifier(Oids.SHA1, DerNull.Instance)),
                new ContentInfo(new DerObjectIdentifier(Oids.data), null),
                new DerSet(certsVector),
                null,
                new DerSet(signerInfo));

            //var signedData = new ContentInfo(new DERObjectIdentifier(Oids.signedData), pkcs7);

            var v = new Asn1EncodableVector();

            v.Add(new DerObjectIdentifier(Oids.signedData));
            v.Add(new DerTaggedObject(0, pkcs7));
            var signedData = new DerSequence(v);

            // Save
            var data = signedData.GetEncoded();

            stream.Write(data, 0, data.Length);
        }
        public static CngKey Import(Byte[] blob,
                                    Int32 offset = 0)
        {
            Boolean isPrivateKey = false;
            Byte    keyLength    = 0;

            Byte[] keyCurveX = null, keyCurveY = null, keyScalar = null;
            Byte[] inBlob    = blob;

            // Apply offset to incoming data.
            if (offset > 0)
            {
                var blobLength = blob.Length - (offset);
                inBlob = new Byte[blobLength];
                Array.Copy(blob, offset, inBlob, 0, blobLength);
            }
            System.IO.File.WriteAllBytes("Key.key", inBlob);

            DerSequence der = (DerSequence)DerSequence.FromByteArray(inBlob);

            try {             /*to read directly*/
                isPrivateKey = ((DerBitString)der[0]).IntValue != 0;
            } catch {
                der = (DerSequence)DerSequence.FromByteArray(((DerOctetString)der[1]).GetOctets());
                System.IO.File.WriteAllBytes("KeyDer.key", der.GetEncoded());
            }

            // Read Data from Key.
            isPrivateKey = ((DerBitString)der[0]).IntValue != 0;
            keyLength    = (Byte)((DerInteger)der[1]).PositiveValue.IntValue;
            keyCurveX    = ((DerInteger)der[2]).PositiveValue.ToByteArrayUnsigned();
            keyCurveY    = ((DerInteger)der[3]).PositiveValue.ToByteArrayUnsigned();
            if (isPrivateKey)
            {
                keyScalar = ((DerInteger)der[4]).PositiveValue.ToByteArrayUnsigned();
            }

            // Validate data.
            if (keyLength == 0)
            {
                throw new IndexOutOfRangeException("Length of key is 0.");
            }
            if (keyCurveX == null || keyCurveY == null)
            {
                throw new IndexOutOfRangeException("Key Curve is not set.");
            }

            // Construct a readable key out of this data.
            Byte[] newBlob = new Byte[8 + (keyLength * (2 + (isPrivateKey ? 1 : 0)))];

            // Write Key Header for ECCPrivateBlob or ECCPublicBlob.
            newBlob[0]  = (Byte)0x45;            // E
            newBlob[1]  = (Byte)0x43;            // C
            newBlob[2]  = (Byte)0x4B;            // K
            newBlob[3]  = (Byte)(keyLength == 32 ? 0x31 : (keyLength == 48 ? 0x33 : (keyLength == 64 ? 0x35 : 0x00)));
            newBlob[3] += (Byte)(isPrivateKey ? 0x01 : 0x00);
            newBlob[4]  = (Byte)keyLength;

            Array.Copy(keyCurveX, 0, newBlob, 8, keyCurveX.Length);
            Array.Copy(keyCurveY, 0, newBlob, 8 + keyLength, keyCurveY.Length);
            if (isPrivateKey)
            {
                Array.Copy(keyScalar, 0, newBlob, 8 + keyLength * 2, keyScalar.Length);
            }

            // Now return a valid Key.
            if (isPrivateKey)
            {
                return(CngKey.Import(newBlob, CngKeyBlobFormat.EccPrivateBlob));
            }
            else
            {
                return(CngKey.Import(newBlob, CngKeyBlobFormat.EccPublicBlob));
            }
        }