示例#1
0
        /// <summary>
        /// Creates a signature from the given <paramref name="message"/>.
        /// <para>
        /// A created signature can be verified by the corresponding
        /// <see cref="PublicKey"/>.
        /// </para>
        /// <para>
        /// Signatures can be created by only the <see cref="PrivateKey"/>
        /// which corresponds a <see cref="PublicKey"/> to verify these
        /// signatures.
        /// </para>
        /// <para>
        /// To sum up, a signature is used to guarantee:
        /// </para>
        /// <list type="bullet">
        /// <item><description>that the <paramref name="message"/> was created
        /// by someone possessing the corresponding <see cref="PrivateKey"/>,
        /// </description></item>
        /// <item><description>that the possessor cannot deny having sent the
        /// <paramref name="message"/>, and</description></item>
        /// <item><description>that the <paramref name="message"/> was not
        /// forged in the middle of transit.</description></item>
        /// </list>
        /// </summary>
        /// <param name="message">A message to sign in <see cref="byte"/> array
        /// representation.</param>
        /// <returns>A signature that verifies the <paramref name="message"/>.
        /// It can be verified using
        /// <see cref="Libplanet.Crypto.PublicKey.Verify(byte[], byte[])"/>
        /// method.</returns>
        /// <seealso cref="Libplanet.Crypto.PublicKey.Verify(byte[], byte[])"/>
        public byte[] Sign(byte[] message)
        {
            var h      = new Sha256Digest();
            var hashed = new byte[h.GetDigestSize()];

            h.BlockUpdate(message, 0, message.Length);
            h.DoFinal(hashed, 0);
            h.Reset();

            var kCalculator = new HMacDsaKCalculator(h);
            var signer      = new ECDsaSigner(kCalculator);

            signer.Init(true, keyParam);
            BigInteger[] rs = signer.GenerateSignature(hashed);
            var          r  = rs[0];
            var          s  = rs[1];

            BigInteger otherS = keyParam.Parameters.N.Subtract(s);

            if (s.CompareTo(otherS) == 1)
            {
                s = otherS;
            }

            var bos = new MemoryStream(72);
            var seq = new DerSequenceGenerator(bos);

            seq.AddObject(new DerInteger(r));
            seq.AddObject(new DerInteger(s));
            seq.Close();
            return(bos.ToArray());
        }
示例#2
0
        public void Dispose()
        {
            _sha?.Reset();
            _sha = null;

            if (_pk != null)
            {
                var tbigint = typeof(BigInteger);
                var tPriv   = typeof(ECPrivateKeyParameters);
                var tints   = typeof(int[]);
                var tint    = typeof(int);
                foreach (var f in tPriv.GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
                         .Where(x => x.FieldType == tbigint))
                {
                    BigInteger v = (BigInteger)f.GetValue(_pk);
                    f.SetValue(_pk, BigInteger.Zero);

                    foreach (var g in tbigint.GetFields(BindingFlags.Instance | BindingFlags.NonPublic))
                    {
                        if (g.FieldType == tint)
                        {
                            g.SetValue(v, 0);
                        }
                        else if (g.FieldType == tints)
                        {
                            Array bytes = (Array)g.GetValue(v);
                            Array.Clear(bytes, 0, bytes.Length);
                        }
                    }
                }

                _pk = null;
            }
        }
示例#3
0
        /// <summary>
        /// Creates a signature from the given <paramref name="message"/>.
        /// <para>
        /// A created signature can be verified by the corresponding
        /// <see cref="PublicKey"/>.
        /// </para>
        /// <para>
        /// Signatures can be created by only the <see cref="PrivateKey"/>
        /// which corresponds a <see cref="PublicKey"/> to verify these
        /// signatures.
        /// </para>
        /// <para>
        /// To sum up, a signature is used to guarantee:
        /// </para>
        /// <list type="bullet">
        /// <item><description>that the <paramref name="message"/> was created
        /// by someone possessing the corresponding <see cref="PrivateKey"/>,
        /// </description></item>
        /// <item><description>that the possessor cannot deny having sent the
        /// <paramref name="message"/>, and</description></item>
        /// <item><description>that the <paramref name="message"/> was not
        /// forged in the middle of transit.</description></item>
        /// </list>
        /// </summary>
        /// <param name="message">A message to sign in <see cref="byte"/> array
        /// representation.</param>
        /// <returns>A signature that verifies the <paramref name="message"/>.
        /// It can be verified using
        /// <see cref="Libplanet.Crypto.PublicKey.Verify(byte[], byte[])"/>
        /// method.</returns>
        /// <seealso cref="Libplanet.Crypto.PublicKey.Verify(byte[], byte[])"/>
        public byte[] Sign(byte[] message)
        {
            var h      = new Sha256Digest();
            var hashed = new byte[h.GetDigestSize()];

            h.BlockUpdate(message, 0, message.Length);
            h.DoFinal(hashed, 0);
            h.Reset();

            return(CryptoConfig.CryptoBackend.Sign(new HashDigest <SHA256>(hashed), this));
        }
示例#4
0
        /// <summary>
        /// From a single given key create a hashname with the intermediate hashes of other keys
        /// </summary>
        /// <returns>The key.</returns>
        /// <param name="csid">The identifier for the cipher set as a string.</param>
        /// <param name="keyData">The key data for the given csid.</param>
        /// <param name="intermediates">Intermediates.</param>
        public static string FromKey(string csid, byte[] keyData, IDictionary <string, string> intermediates)
        {
            Sha256Digest  digest = new Sha256Digest();
            List <string> keys   = new List <string>(intermediates.Keys);

            keys.Add(csid);
            keys.Sort();

            int digestSize = digest.GetDigestSize();

            byte[] outhash = null;
            foreach (var key in keys)
            {
                if (outhash != null)
                {
                    digest.BlockUpdate(outhash, 0, digestSize);
                }
                else
                {
                    outhash = new byte[digestSize];
                }
                byte inByte;
                try {
                    inByte = Convert.ToByte(key, 16);
                } catch (FormatException) {
                    return(null);
                } catch (OverflowException) {
                    return(null);
                } catch (ArgumentException) {
                    return(null);
                }
                digest.Update(inByte);
                digest.DoFinal(outhash, 0);
                digest.Reset();

                digest.BlockUpdate(outhash, 0, digestSize);
                if (key == csid)
                {
                    Sha256Digest keyDigest = new Sha256Digest();
                    keyDigest.BlockUpdate(keyData, 0, keyData.Length);
                    keyDigest.DoFinal(outhash, 0);
                    digest.BlockUpdate(outhash, 0, outhash.Length);
                }
                else
                {
                    byte[] keyIntermediate = Base32Encoder.Decode(intermediates [key]);
                    digest.BlockUpdate(keyIntermediate, 0, keyIntermediate.Length);
                }
                digest.DoFinal(outhash, 0);
            }
            return(Base32Encoder.Encode(outhash).TrimEnd(trimChars).ToLower());
        }
示例#5
0
        public static string FromKeys(IDictionary <string, string> publicKeys)
        {
            // You've gotta have some keys to hash!
            if (publicKeys.Count <= 0)
            {
                return(null);
            }
            Sha256Digest  digest = new Sha256Digest();
            List <string> keys   = new List <string>(publicKeys.Keys);

            keys.Sort();

            int digestSize = digest.GetDigestSize();

            byte[] outhash = null;
            foreach (var key in keys)
            {
                if (outhash != null)
                {
                    digest.BlockUpdate(outhash, 0, digestSize);
                }
                else
                {
                    outhash = new byte[digestSize];
                }
                byte inByte;
                try {
                    inByte = Convert.ToByte(key, 16);
                } catch (FormatException) {
                    return(null);
                } catch (OverflowException) {
                    return(null);
                } catch (ArgumentException) {
                    return(null);
                }
                digest.Update(inByte);
                digest.DoFinal(outhash, 0);
                digest.Reset();

                digest.BlockUpdate(outhash, 0, digestSize);
                byte[]       keyData   = Base32Encoder.Decode(publicKeys [key]);
                Sha256Digest keyDigest = new Sha256Digest();
                keyDigest.BlockUpdate(keyData, 0, keyData.Length);
                keyDigest.DoFinal(outhash, 0);
                digest.BlockUpdate(outhash, 0, outhash.Length);
                digest.DoFinal(outhash, 0);
            }
            return(Base32Encoder.Encode(outhash).TrimEnd(trimChars).ToLower());
        }
示例#6
0
        /// <summary>
        /// Hashes the key for keyczar version look ups.
        /// </summary>
        /// <param name="size">The size.</param>
        /// <param name="components">The components.</param>
        /// <returns></returns>
        public static byte[] UnofficalHashKey(int size, params byte[][] components)
        {
            var sha1 = new Sha256Digest();

            foreach (var data in components)
            {
                sha1.BlockUpdate(data, 0, data.Length);
            }

            var hash = new byte[sha1.GetDigestSize()];

            sha1.DoFinal(hash, 0);
            sha1.Reset();
            var outBytes = new byte[size];

            Array.Copy(hash, 0, outBytes, 0, outBytes.Length);
            return(outBytes);
        }
示例#7
0
        public bool Verify(byte[] message, byte[] signature)
        {
            if (message == null)
            {
                throw new ArgumentNullException(nameof(message));
            }

            if (signature == null)
            {
                throw new ArgumentNullException(nameof(signature));
            }

            var h      = new Sha256Digest();
            var hashed = new byte[h.GetDigestSize()];

            h.BlockUpdate(message, 0, message.Length);
            h.DoFinal(hashed, 0);
            h.Reset();

            return(CryptoConfig.CryptoBackend.Verify(
                       new HashDigest <SHA256>(hashed),
                       signature,
                       this));
        }
示例#8
0
        private byte[] KDF(byte[] secret, int cbitKey, string algorithmID)
        {
            //  Build a long byte array
            //  four byte counter
            //  secret
            //  AlgorithmID - [32-bit size || algorithm identifier ]
            //  PartyUInfo - [32-bit size || PartyUInfo ] ---- "apu"
            //  PartyVInfo - [32-bit size || PartyVInfo ] ---- "apv"
            //  SuppPubInfo - 32-bit - key data len
            //  SuppPrivInfo - nothing

            byte[] rgbPartyU = new byte[0];
            byte[] rgbPartyV = new byte[0];
            byte[] algId     = UTF8Encoding.UTF8.GetBytes(algorithmID);

            JSON j = FindAttribute("apu");

            if (j != null)
            {
                rgbPartyU = j.AsBytes();
            }

            j = FindAttribute("apv");
            if (j != null)
            {
                rgbPartyV = j.AsBytes();
            }

            int c = 4 + secret.Length + 4 + algId.Length + 4 + rgbPartyU.Length + 4 + rgbPartyV.Length + 4;

            byte[] rgb = new byte[c];

            //  Counter starts at 0

            Array.Copy(secret, 0, rgb, 4, secret.Length);
            c = 4 + secret.Length;

            if (algorithmID.Length > 255)
            {
                throw new Exception("Internal error");
            }
            rgb[c + 3] = (byte)algId.Length;
            Array.Copy(algId, 0, rgb, c + 4, algId.Length);
            c += 4 + algorithmID.Length;

            if (rgbPartyU.Length > 255)
            {
                throw new Exception("Internal error");
            }
            rgb[c + 3] = (byte)rgbPartyU.Length;
            Array.Copy(rgbPartyU, 0, rgb, c + 4, rgbPartyU.Length);
            c += 4 + rgbPartyU.Length;

            if (rgbPartyV.Length > 255)
            {
                throw new Exception("internal error");
            }
            rgb[c + 3] = (byte)rgbPartyV.Length;
            Array.Copy(rgbPartyV, 0, rgb, c + 4, rgbPartyV.Length);
            c += 4 + rgbPartyV.Length;

            if (cbitKey / (256 * 256) != 0)
            {
                throw new Exception("internal error");
            }
            rgb[c + 3] = (byte)(cbitKey % 256);
            rgb[c + 2] = (byte)(cbitKey / 256);

            //  Now do iterative hashing

            IDigest digest = new Sha256Digest();
            int     cIters = (cbitKey + 255) / 256;

            byte[] rgbDigest = new byte[256 / 8 * cIters];

            for (int i = 0; i < cIters; i++)
            {
                rgb[3] = (byte)(i + 1);
                digest.Reset();
                digest.BlockUpdate(rgb, 0, rgb.Length);
                digest.DoFinal(rgbDigest, (256 / 8) * i);
            }

            byte[] rgbOut = new byte[cbitKey / 8];
            Array.Copy(rgbDigest, rgbOut, rgbOut.Length);
            return(rgbOut);

            /*
             *                     //  Do the KDF function
             *
             *      CBORObject dataArray = CBORObject.NewArray();
             *      dataArray.Add(0);
             *      dataArray.Add(k1.ToByteArray());
             *
             *      string PartyUInfo = null;
             *      if (objUnprotected.ContainsKey("PartyUInfo")) PartyUInfo = objUnprotected["PartyUInfo"].AsString();
             *      dataArray.Add(PartyUInfo);
             *
             *      string PartyVInfo = null;
             *      if (objUnprotected.ContainsKey("PartyVInfo")) PartyUInfo = objUnprotected["PartyVInfo"].AsString();
             *      dataArray.Add(PartyVInfo);
             *
             *      byte[] SubPubInfo = new byte[4];
             *      SubPubInfo[3] = (byte) cbitKey;
             *      dataArray.Add(SubPubInfo);
             *
             *      dataArray.Add(null); // SubPrivInfo
             *
             *      byte[] rgbData = dataArray.EncodeToBytes();
             *      Sha256Digest sha256 = new Sha256Digest();
             *      sha256.BlockUpdate(rgbData, 0, rgbData.Length);
             *      byte[] rgbOut = new byte[sha256.GetByteLength()];
             *      sha256.DoFinal(rgbOut, 0);
             *
             *      byte[] rgbResult = new byte[cbitKey / 8];
             *      Array.Copy(rgbOut, rgbResult, rgbResult.Length);
             */
        }
示例#9
0
        private byte[] Kdf(byte[] secret, EncryptMessage msg, int cbitKey, string algorithmId)
        {
            //  Build a long byte array
            //  four byte counter
            //  secret
            //  AlgorithmID - [32-bit size || algorithm identifier ]
            //  PartyUInfo - [32-bit size || PartyUInfo ] ---- "apu"
            //  PartyVInfo - [32-bit size || PartyVInfo ] ---- "apv"
            //  SuppPubInfo - 32-bit - key data len
            //  SuppPrivInfo - nothing

            byte[] rgbPartyU = new byte[0];
            byte[] rgbPartyV = new byte[0];
            byte[] algId     = Encoding.UTF8.GetBytes(algorithmId);

            CBORObject j = FindAttr("apu", msg);

            if (j != null)
            {
                rgbPartyU = Message.base64urldecode(j.AsString());
            }

            j = FindAttr("apv", msg);
            if (j != null)
            {
                rgbPartyV = Message.base64urldecode(j.AsString());
            }

            int c = 4 + secret.Length + 4 + algId.Length + 4 + rgbPartyU.Length + 4 + rgbPartyV.Length + 4;

            byte[] rgb = new byte[c];

            //  Counter starts at 0

            Array.Copy(secret, 0, rgb, 4, secret.Length);
            c = 4 + secret.Length;

            if (algorithmId.Length > 255)
            {
                throw new JoseException("Internal error");
            }
            rgb[c + 3] = (byte)algId.Length;
            Array.Copy(algId, 0, rgb, c + 4, algId.Length);
            c += 4 + algorithmId.Length;

            if (rgbPartyU.Length > 255)
            {
                throw new JoseException("Internal error");
            }
            rgb[c + 3] = (byte)rgbPartyU.Length;
            Array.Copy(rgbPartyU, 0, rgb, c + 4, rgbPartyU.Length);
            c += 4 + rgbPartyU.Length;

            if (rgbPartyV.Length > 255)
            {
                throw new JoseException("internal error");
            }
            rgb[c + 3] = (byte)rgbPartyV.Length;
            Array.Copy(rgbPartyV, 0, rgb, c + 4, rgbPartyV.Length);
            c += 4 + rgbPartyV.Length;

            if (cbitKey / (256 * 256) != 0)
            {
                throw new JoseException("internal error");
            }
            rgb[c + 3] = (byte)(cbitKey % 256);
            rgb[c + 2] = (byte)(cbitKey / 256);

            //  Now do iterative hashing

            IDigest digest = new Sha256Digest();
            int     cIters = (cbitKey + 255) / 256;

            byte[] rgbDigest = new byte[256 / 8 * cIters];

            for (int i = 0; i < cIters; i++)
            {
                rgb[3] = (byte)(i + 1);
                digest.Reset();
                digest.BlockUpdate(rgb, 0, rgb.Length);
                digest.DoFinal(rgbDigest, (256 / 8) * i);
            }

            byte[] rgbOut = new byte[cbitKey / 8];
            Array.Copy(rgbDigest, rgbOut, rgbOut.Length);
            return(rgbOut);
        }
示例#10
0
 public void Dispose()
 {
     _sha?.Reset();
     _sha = null;
 }
示例#11
0
 public void Reset()
 {
     _sha.Reset();
 }