Beispiel #1
0
        public static uint256 Hash256(byte[] data, int offset, int count)
        {
            //data = count == 0 ? new byte[1] : data;
#if !USEBC
            using (var sha = new SHA256Managed())
            {
                var h = sha.ComputeHash(data, offset, count);
                return(new uint256(sha.ComputeHash(h, 0, h.Length)));
            }
#else
            Sha256Digest sha256 = new Sha256Digest();
            sha256.BlockUpdate(data, offset, count);
            byte[] rv = new byte[32];
            sha256.DoFinal(rv, 0);
            sha256.BlockUpdate(rv, 0, rv.Length);
            sha256.DoFinal(rv, 0);
            return(new uint256(rv));
#endif
        }
Beispiel #2
0
        private byte[] GenerateSeed()
        {
            //Hash the passphrasse 50,000 times
            var passPhraseBytes = new byte[_password.Length * sizeof(char)];

            Buffer.BlockCopy(_password.ToCharArray(), 0, passPhraseBytes, 0, passPhraseBytes.Length);
            var digester = new Sha256Digest();
            var seed     = new byte[digester.GetDigestSize()];

            digester.BlockUpdate(seed, 0, seed.Length);
            digester.DoFinal(seed, 0);
            for (var i = 0; i < 49999; i++)
            {
                digester = new Sha256Digest();
                digester.BlockUpdate(seed, 0, seed.Length);
                digester.DoFinal(seed, 0);
            }
            return(seed);
        }
Beispiel #3
0
        static byte[] GenerateAESKey(ECPublicKeyParameters bobPublicKey,
                                     AsymmetricKeyParameter alicePrivateKey)
        {
            ECDHBasicAgreement aKeyAgree = new ECDHBasicAgreement();

            aKeyAgree.Init(alicePrivateKey);
            byte[] sharedSecret = aKeyAgree.CalculateAgreement(bobPublicKey).ToByteArray();

            // make sure each part has the correct and same size
            ResizeRight(ref sharedSecret, 66); // 66 is the desired key size

            Sha256Digest digest = new Sha256Digest();

            byte[] symmetricKey = new byte[digest.GetDigestSize()];
            digest.BlockUpdate(sharedSecret, 0, sharedSecret.Length);
            digest.DoFinal(symmetricKey, 0);

            return(symmetricKey);
        }
Beispiel #4
0
        private static string ByteArrayToBase58Check(byte[] ba)
        {
            byte[] bb = new byte[ba.Length + 4];
            Array.Copy(ba, bb, ba.Length);
            Sha256Digest bcsha256a = new Sha256Digest();

            bcsha256a.BlockUpdate(ba, 0, ba.Length);
            byte[] thehash = new byte[32];
            bcsha256a.DoFinal(thehash, 0);
            bcsha256a.BlockUpdate(thehash, 0, 32);
            bcsha256a.DoFinal(thehash, 0);

            for (int i = 0; i < 4; i++)
            {
                bb[ba.Length + i] = thehash[i];
            }

            return(FromByteArray(bb));
        }
Beispiel #5
0
        /// <summary>
        /// Calculate the signature of <paramref name="data"/>
        /// </summary>
        /// <param name="data">The data to sign</param>
        /// <param name="consumerSecret">The consumer secret</param>
        /// <param name="tokenSecret">The token secret</param>
        /// <returns>The signature</returns>
        public string CalculateSignature(byte[] data, string consumerSecret, string tokenSecret)
        {
            var key     = $"{consumerSecret}&{tokenSecret}";
            var keyData = _encoding.GetBytes(key);

#if USE_BOUNCYCASTLE
            var digest = new Sha256Digest();
            var crypto = new HMac(digest);
            crypto.Init(new KeyParameter(keyData));
            crypto.BlockUpdate(data, 0, data.Length);
            var hash = MacUtilities.DoFinal(crypto);
            return(System.Convert.ToBase64String(hash));
#else
            using (var digest = new HMACSHA256(keyData))
            {
                var hash = digest.ComputeHash(data);
                return(System.Convert.ToBase64String(hash));
            }
#endif
        }
Beispiel #6
0
        public static string GeradorHashCode(string mensagem)
        {
            // 1- Pega os bytes da mesagem
            byte[] bitsMensagem = Encoding.UTF8.GetBytes(mensagem);

            // 2- Cria o objeto SHA256 que irá calcular o hash da mesagem
            Sha256Digest CalculaHash = new Sha256Digest();

            CalculaHash.BlockUpdate(bitsMensagem, 0, bitsMensagem.Length);

            // 3- Executa o método [ComputeHash] para calcular o Hash e retornar os bytes
            byte[] BytesHash = new byte[CalculaHash.GetDigestSize()];
            CalculaHash.DoFinal(BytesHash, 0);

            // 4- Converte os bytes para hexadecimal e retorna um array de bytes
            byte[] sha256hex2 = Hex.Encode(BytesHash);
            // 4.1- Convert em uma string o array de bytes
            string sha256hex = Encoding.UTF8.GetString(sha256hex2).ToLower();

            return(sha256hex);
        }
Beispiel #7
0
        public byte[] CalculateSharedSecret(byte[] remotePublicKey)
        {
            if (!m_bInited)
            {
                Init();
            }
            DHPublicKeyParameters remoteKeyParameters = new DHPublicKeyParameters(new BigInteger(1, remotePublicKey), m_dhParameters);
            DHBasicAgreement      agreement           = new DHBasicAgreement();

            agreement.Init(m_keyPair.Private);
            byte[] resAgreement = agreement.CalculateAgreement(remoteKeyParameters).ToByteArrayUnsigned();

            Sha256Digest digest = new Sha256Digest();

            byte[] resHash = new byte[digest.GetDigestSize()];
            digest.BlockUpdate(resAgreement, 0, resAgreement.Length);
            digest.DoFinal(resHash, 0);

            SharedSecret = resHash;
            return(resHash);
        }
Beispiel #8
0
        public static byte[] DoSignEcDsaSha256P256_old(IEnumerable <BufLen> bufs, I2PSigningPrivateKey key)
        {
            var sha = new Sha256Digest();

            foreach (var buf in bufs)
            {
                sha.BlockUpdate(buf.BaseArray, buf.BaseArrayOffset, buf.Length);
            }
            var hash = new byte[sha.GetDigestSize()];

            sha.DoFinal(hash, 0);

            var p     = Org.BouncyCastle.Asn1.Nist.NistNamedCurves.GetByName("P-256");
            var param = new ECDomainParameters(p.Curve, p.G, p.N, p.H);
            var pk    = new ECPrivateKeyParameters(key.ToBigInteger(), param);

            var s = new Org.BouncyCastle.Crypto.Signers.ECDsaSigner();

            s.Init(true, new ParametersWithRandom(pk));

            var sig    = s.GenerateSignature(hash);
            var result = new byte[64];

            var b1 = sig[0].ToByteArrayUnsigned();
            var b2 = sig[1].ToByteArrayUnsigned();

            // https://geti2p.net/en/docs/spec/common-structures#type_Signature
            // When a signature is composed of two elements (for example values R,S),
            // it is serialized by padding each element to length/2 with leading zeros if necessary.
            // All types are Big Endian, except for EdDSA, which is stored and transmitted in a Little Endian format.

            // Pad msb. Big endian.
            Array.Copy(b1, 0, result, 0 + 20 - b1.Length, b1.Length);
            Array.Copy(b2, 0, result, 20 + 20 - b2.Length, b2.Length);

            DebugUtils.LogDebug("DoSignEcDsaSha256P256: Used.");

            return(result);
        }
        public static string HashSomething(string password, string something)
        {
            var dig = new Sha256Digest();
            byte[] bpassword = Encoding.UTF8.GetBytes(password);
            dig.BlockUpdate(bpassword, 0, bpassword.Length);
            var key = new byte[dig.GetDigestSize()];
            dig.DoFinal(key, 0);

            var hmac = new HMac(new Sha256Digest());
            hmac.Init(new KeyParameter(key));
            byte[] input = Encoding.UTF8.GetBytes(something);
            hmac.BlockUpdate(input, 0, input.Length);
            var output = new byte[hmac.GetMacSize()];
            hmac.DoFinal(output, 0);

            var sb = new StringBuilder(output.Length*2);
            foreach (byte b in output)
            {
                sb.AppendFormat("{0:x2}", b);
            }
            return sb.ToString();
        }
        /// <summary>
        /// Generate a DSA2 Key pair given its bit size.
        /// </summary>
        /// <param name="keySize">"Key bit size of 1024, 2048 or 3072"</param>
        /// <returns>"DSA2 key pair for the given size"</returns>
        public AsymmetricCipherKeyPair Dsa2KeyGen(int keySize)
        {
            // Check that we got a proper key size
            int[] allowedKeySizes = { 1024, 2048, 3072 };
            if (!(allowedKeySizes.Contains(keySize)))
            {
                throw new ArgumentException("KeySize provided is not 1024, 2048 or 3072.", "keySize");
            }

            // Set the proper N parameter depending on the bit key size.
            int dsa2NParam;

            if (keySize == 1024)
            {
                dsa2NParam = 160;
            }
            else
            {
                dsa2NParam = 256;
            }

            var secRand      = new SecureRandom();
            var dsa2Genertor = GeneratorUtilities.GetKeyPairGenerator("DSA");

            // Generate the proper parameters for the DSA2 Key.
            var digest        = new Sha256Digest();
            var paramGen      = new DsaParametersGenerator(digest);
            var dsaParamsList = new DsaParameterGenerationParameters(keySize, dsa2NParam, 80, secRand);

            paramGen.Init(dsaParamsList);

            // This will take a while since it has to find a valid random prime number for use.
            var dsaParams = paramGen.GenerateParameters();

            var dsaOptions = new DsaKeyGenerationParameters(secRand, dsaParams);
            var keyPair    = dsa2Genertor.GenerateKeyPair();

            return(keyPair);
        }
        private IDigest GetDigest(THashAlgorithm hashAlgorithm)
        {
            IDigest result = null;

            switch (hashAlgorithm)
            {
            case THashAlgorithm.None:
                result = new NullDigest();
                break;

            case THashAlgorithm.MD5:
                result = new MD5Digest();
                break;

            case THashAlgorithm.SHA1:
                result = new Sha1Digest();
                break;

            case THashAlgorithm.SHA224:
                result = new Sha224Digest();
                break;

            case THashAlgorithm.SHA256:
                result = new Sha256Digest();
                break;

            case THashAlgorithm.SHA384:
                result = new Sha384Digest();
                break;

            case THashAlgorithm.SHA512:
                result = new Sha512Digest();
                break;

            default:
                break;
            }
            return(result);
        }
Beispiel #12
0
            private byte[] ComputePubPart(int i, int two2H)
            {
                Sha256Digest digest = new Sha256Digest();

                digest.BlockUpdate(Identifier, 0, Identifier.Length);
                digest.BlockUpdate(u32str(i), 0, 4);
                if (i >= two2H)
                {
                    digest.BlockUpdate(D_LEAF, 0, 2);
                    digest.BlockUpdate(LmtosPublic(i - two2H), 24, 32);
                }
                else
                {
                    digest.BlockUpdate(D_INTR, 0, 2);
                    digest.BlockUpdate(ComputePubPart(i * 2, two2H), 0, 32);
                    digest.BlockUpdate(ComputePubPart(i * 2 + 1, two2H), 0, 32);
                }

                byte[] result = new byte[32];
                digest.DoFinal(result, 0);
                return(result);
            }
        public byte[] GetHash(byte[] input, int times = 1)
        {
            if (times <= 0)
            {
                throw new ArgumentException("times should be more than 0", nameof(times));
            }

            var digest    = new Sha256Digest();
            var saltBytes = new byte[input.Length];

            byte[] result = null;
            Array.Copy(input, saltBytes, input.Length);

            for (int i = 0; i < times; i++)
            {
                digest.BlockUpdate(saltBytes, 0, saltBytes.Length);
                result = new byte[digest.GetDigestSize()];
                digest.DoFinal(result, 0);
            }

            return(result);
        }
        /// <summary>
        /// Converts a base-58 string to a byte array, checking the checksum, and
        /// returning null if it wasn't valid.  Appending "?" to the end of the string skips
        /// the checksum calculation, but still strips the four checksum bytes from the
        /// result.
        /// </summary>
        public static byte[] Base58CheckToByteArray(string base58)
        {
            bool IgnoreChecksum = false;

            if (base58.EndsWith("?"))
            {
                IgnoreChecksum = true;
                base58         = base58.Substring(0, base58.Length - 1);
            }

            byte[] bb = Base58.ToByteArray(base58);
            if (bb == null || bb.Length < 4)
            {
                return(null);
            }

            if (IgnoreChecksum == false)
            {
                Sha256Digest bcsha256a = new Sha256Digest();
                bcsha256a.BlockUpdate(bb, 0, bb.Length - 4);

                byte[] checksum = new byte[32];  //sha256.ComputeHash(bb, 0, bb.Length - 4);
                bcsha256a.DoFinal(checksum, 0);
                bcsha256a.BlockUpdate(checksum, 0, 32);
                bcsha256a.DoFinal(checksum, 0);

                for (int i = 0; i < 4; i++)
                {
                    if (checksum[i] != bb[bb.Length - 4 + i])
                    {
                        return(null);
                    }
                }
            }

            byte[] rv = new byte[bb.Length - 4];
            Array.Copy(bb, 0, rv, 0, bb.Length - 4);
            return(rv);
        }
        internal override ISigner GetSigner()
        {
            IDigest digest;

            if (Digest == DigestAlg.Sha224)
            {
                digest = new Sha224Digest();
            }
            else if (Digest == DigestAlg.Sha256)
            {
                digest = new Sha256Digest();
            }
            else if (Digest == DigestAlg.Sha384)
            {
                digest = new Sha384Digest();
            }
            else if (Digest == DigestAlg.Sha512)
            {
                digest = new Sha512Digest();
            }
            else if (Digest == DigestAlg.Sha1)
            {
                digest = new Sha1Digest();
            }
            else
            {
                throw new InvalidKeyTypeException($"Unknown digest type :{Digest}");
            }
            if (Padding == PaddingAlg.Pss)
            {
                return(new PssSigner(new RsaBlindedEngine(), digest));
            }
            if (Padding == PaddingAlg.Pkcs15)
            {
                return(new RsaDigestSigner(digest));
            }

            throw new InvalidKeyTypeException($"Unknown padding type :{Padding}");
        }
Beispiel #16
0
        /// <summary>
        /// Get Switcheo NEO Signature
        /// </summary>
        /// <param name="message">Message to sign</param>
        /// <param name="privateKey">Private key of wallet</param>
        /// <returns>String  of signed message</returns>
        private string GetSwitcheoNeoSignature(byte[] message, byte[] privateKey)
        {
            var curve  = SecNamedCurves.GetByName("secp256r1");
            var domain = new ECDomainParameters(curve.Curve, curve.G, curve.N, curve.H);

            var priv   = new ECPrivateKeyParameters("ECDSA", (new Org.BouncyCastle.Math.BigInteger(1, privateKey)), domain);
            var signer = new ECDsaSigner();

            var hash = new Sha256Digest();

            hash.BlockUpdate(message, 0, message.Length);

            var result = new byte[32];

            hash.DoFinal(result, 0);

            message = result;

            signer.Init(true, priv);
            var signature = signer.GenerateSignature(message);

            return(ProcessNeoSignature(signature));
        }
Beispiel #17
0
        public static byte[] SignRFC6979(this ECDsa key, byte[] data)
        {
            var digest        = new Sha256Digest();
            var secp256r1     = SecNamedCurves.GetByName("secp256r1");
            var ec_parameters = new ECDomainParameters(secp256r1.Curve, secp256r1.G, secp256r1.N);
            var private_key   = new ECPrivateKeyParameters(new BigInteger(1, key.PrivateKey()), ec_parameters);
            var signer        = new ECDsaSigner(new HMacDsaKCalculator(digest));
            var hash          = new byte[digest.GetDigestSize()];

            digest.BlockUpdate(data, 0, data.Length);
            digest.DoFinal(hash, 0);
            signer.Init(true, private_key);
            var rs        = signer.GenerateSignature(hash);
            var signature = new byte[RFC6979SignatureSize];
            var rbytes    = rs[0].ToByteArrayUnsigned();
            var sbytes    = rs[1].ToByteArrayUnsigned();
            var index     = RFC6979SignatureSize / 2 - rbytes.Length;

            rbytes.CopyTo(signature, index);
            index = RFC6979SignatureSize - sbytes.Length;
            sbytes.CopyTo(signature, index);
            return(signature);
        }
Beispiel #18
0
        /// <summary>
        /// Hash stream with SHA256
        /// </summary>
        /// <param name="input">Input stream</param>
        /// <param name="bufferSize">Buffer size</param>
        /// <returns>Hash</returns>
        public static byte[] Hash(Stream input, int bufferSize = 4096)
        {
            byte[] result = new byte[32];

            Sha256Digest sha256 = new Sha256Digest();
            int          bytesRead;

            byte[] buffer = new byte[bufferSize];

            do
            {
                bytesRead = input.Read(buffer, 0, bufferSize);
                if (bytesRead > 0)
                {
                    sha256.BlockUpdate(buffer, 0, bytesRead);
                }
            } while (bytesRead == bufferSize);


            sha256.DoFinal(result, 0);

            return(result);
        }
        public Srp6MultiStepService(ITimeService time, IPowService pow)
        {
            _time         = time;
            _pow          = pow;
            _cryptoRandom = new SecureRandom(new CryptoApiRandomGenerator());
            _sessions     = new ConcurrentDictionary <long, Srp6Context>();
            _hash         = new Sha256Digest();

            Task.Run(() =>
            {
                for (;;)
                {
                    Thread.Sleep(GlobalConfig.SRP6_SESSION_LIFE_TIME * 1000);
                    var now = _time.UtcNow;

                    var list = _sessions.Where(x => x.Value.Expire < now).Select(x => x.Key).ToImmutableList();
                    foreach (var key in list)
                    {
                        _sessions.TryRemove(key, out _);
                    }
                }
            });
        }
Beispiel #20
0
        void OnSvAppSecureHandshake(string id, JsonObj args)
        {
            // https://davidtavarez.github.io/2019/implementing-elliptic-curve-diffie-hellman-c-sharp/
            X9ECParameters     x9Params     = NistNamedCurves.GetByName("P-521");
            ECDomainParameters domainParams = new ECDomainParameters(x9Params.Curve, x9Params.G, x9Params.N, x9Params.H, x9Params.GetSeed());
            ECKeyPairGenerator generator    = (ECKeyPairGenerator)GeneratorUtilities.GetKeyPairGenerator("ECDH");

            generator.Init(new ECKeyGenerationParameters(domainParams, new SecureRandom()));
            AsymmetricCipherKeyPair aliceKeyPair         = generator.GenerateKeyPair();
            ECPublicKeyParameters   alicePublicKeyParams = (ECPublicKeyParameters)aliceKeyPair.Public;

            string bobKey = args.Get <string>("key");

            byte[] bobKeyBytes = System.Convert.FromBase64String(bobKey);
            var    bobPoint    = x9Params.Curve.DecodePoint(bobKeyBytes);
            ECPublicKeyParameters bobPublicKeyParams = new ECPublicKeyParameters("ECDH", bobPoint, SecObjectIdentifiers.SecP521r1);

            IBasicAgreement agreement = AgreementUtilities.GetBasicAgreement("ECDH");

            agreement.Init(aliceKeyPair.Private);
            BigInteger sharedSecret = agreement.CalculateAgreement(bobPublicKeyParams);

            IDigest digest = new Sha256Digest();

            byte[] sharedSecretBytes = sharedSecret.ToBytes(66);
            digest.BlockUpdate(sharedSecretBytes, 0, sharedSecretBytes.Length);
            derivedKeyBytes = new byte[digest.GetDigestSize()];
            digest.DoFinal(derivedKeyBytes, 0);

            Debug.Log(System.BitConverter.ToString(sharedSecretBytes));
            Debug.Log(System.Convert.ToBase64String(derivedKeyBytes));

            ReturnSuccess(id, new JsonObj()
            {
                ["key"] = alicePublicKeyParams.Q.GetEncoded(),
            });
        }
Beispiel #21
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));
        }
        private void btnConfirm_Click(object sender, EventArgs e)
        {
            lblAddressHeader.Visible = false;
            lblAddressItself.Visible = false;
            lblResult.Visible        = false;


            // check for null entry
            if (txtPassphrase.Text == "")
            {
                MessageBox.Show("Passphrase is required.", "Passphrase required", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            if (txtConfCode.Text == "")
            {
                MessageBox.Show("Confirmation code is required.", "Confirmation code required", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            // Parse confirmation code.
            byte[] confbytes = Util.Base58CheckToByteArray(txtConfCode.Text.Trim());
            if (confbytes == null)
            {
                // is it even close?
                if (txtConfCode.Text.StartsWith("cfrm38"))
                {
                    MessageBox.Show("This is not a valid confirmation code.  It has the right prefix, but " +
                                    "doesn't contain valid confirmation data.  Possible typo or incomplete?",
                                    "Invalid confirmation code", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    return;
                }

                MessageBox.Show("This is not a valid confirmation code.", "Invalid confirmation code", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            if (confbytes.Length != 51 || confbytes[0] != 0x64 || confbytes[1] != 0x3B || confbytes[2] != 0xF6 ||
                confbytes[3] != 0xA8 || confbytes[4] != 0x9A || confbytes[18] < 0x02 || confbytes[18] > 0x03)
            {
                // Unrecognized Base58 object.  Do we know what this is?  Tell the user.
                object result = StringInterpreter.Interpret(txtConfCode.Text.Trim());
                if (result != null)
                {
                    // did we actually get an encrypted private key?  if so, just try to decrypt it.
                    if (result is PassphraseKeyPair)
                    {
                        PassphraseKeyPair ppkp = result as PassphraseKeyPair;
                        if (ppkp.DecryptWithPassphrase(txtPassphrase.Text))
                        {
                            confirmIsValid(ppkp.GetAddress().AddressBase58);
                            MessageBox.Show("What you provided contains a private key, not just a confirmation. " +
                                            "Confirmation is successful, and with this correct passphrase, " +
                                            "you are also able to spend the funds from the address.", "This is actually a private key",
                                            MessageBoxButtons.OK, MessageBoxIcon.Information);
                            return;
                        }
                        else
                        {
                            MessageBox.Show("This is not a valid confirmation code.  It looks like an " +
                                            "encrypted private key.  Decryption was attempted but the passphrase couldn't decrypt it", "Invalid confirmation code", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                            return;
                        }
                    }

                    string objectKind = result.GetType().Name;
                    if (objectKind == "AddressBase")
                    {
                        objectKind = "an Address";
                    }
                    else
                    {
                        objectKind = "a " + objectKind;
                    }

                    MessageBox.Show("This is not a valid confirmation code.  Instead, it looks like " + objectKind +
                                    ".  Perhaps you entered the wrong thing?  Confirmation codes " +
                                    "start with \"cfrm\".", "Invalid confirmation code", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    return;
                }

                MessageBox.Show("This is not a valid confirmation code.", "Invalid confirmation code", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            // extract ownersalt and get an intermediate
            byte[] ownersalt = new byte[8];
            Array.Copy(confbytes, 10, ownersalt, 0, 8);

            bool includeHashStep           = (confbytes[5] & 0x04) == 0x04;
            Bip38Intermediate intermediate = new Bip38Intermediate(txtPassphrase.Text, ownersalt, includeHashStep);

            // derive the 64 bytes we need
            // get ECPoint from passpoint
            PublicKey pk = new PublicKey(intermediate.passpoint);

            byte[] addresshashplusownersalt = new byte[12];
            Array.Copy(confbytes, 6, addresshashplusownersalt, 0, 4);
            Array.Copy(intermediate.ownerentropy, 0, addresshashplusownersalt, 4, 8);

            // derive encryption key material
            byte[] derived = new byte[64];
            CryptSharp.Utility.SCrypt.ComputeKey(intermediate.passpoint, addresshashplusownersalt, 1024, 1, 1, 1, derived);

            byte[] derivedhalf2 = new byte[32];
            Array.Copy(derived, 32, derivedhalf2, 0, 32);

            byte[] unencryptedpubkey = new byte[33];
            // recover the 0x02 or 0x03 prefix
            unencryptedpubkey[0] = (byte)(confbytes[18] ^ (derived[63] & 0x01));

            // decrypt
            var aes = Aes.Create();

            aes.KeySize = 256;
            aes.Mode    = CipherMode.ECB;
            aes.Key     = derivedhalf2;
            ICryptoTransform decryptor = aes.CreateDecryptor();

            decryptor.TransformBlock(confbytes, 19, 16, unencryptedpubkey, 1);
            decryptor.TransformBlock(confbytes, 19, 16, unencryptedpubkey, 1);
            decryptor.TransformBlock(confbytes, 19 + 16, 16, unencryptedpubkey, 17);
            decryptor.TransformBlock(confbytes, 19 + 16, 16, unencryptedpubkey, 17);

            // xor out the padding
            for (int i = 0; i < 32; i++)
            {
                unencryptedpubkey[i + 1] ^= derived[i];
            }

            // reconstitute the ECPoint
            var     ps = Org.BouncyCastle.Asn1.Sec.SecNamedCurves.GetByName("secp256k1");
            ECPoint point;

            try {
                point = ps.Curve.DecodePoint(unencryptedpubkey);

                // multiply passfactor.  Result is going to be compressed.
                ECPoint pubpoint = point.Multiply(new BigInteger(1, intermediate.passfactor));

                // Do we want it uncompressed?  then we will have to uncompress it.
                byte flagbyte = confbytes[5];
                if ((flagbyte & 0x20) == 0x00)
                {
                    pubpoint = ps.Curve.CreatePoint(pubpoint.X.ToBigInteger(), pubpoint.Y.ToBigInteger(), false);
                }

                // Convert to bitcoin address and check address hash.
                PublicKey generatedaddress = new PublicKey(pubpoint);

                // get addresshash
                UTF8Encoding utf8   = new UTF8Encoding(false);
                Sha256Digest sha256 = new Sha256Digest();
                byte[]       generatedaddressbytes = utf8.GetBytes(generatedaddress.AddressBase58);
                sha256.BlockUpdate(generatedaddressbytes, 0, generatedaddressbytes.Length);
                byte[] addresshashfull = new byte[32];
                sha256.DoFinal(addresshashfull, 0);
                sha256.BlockUpdate(addresshashfull, 0, 32);
                sha256.DoFinal(addresshashfull, 0);

                for (int i = 0; i < 4; i++)
                {
                    if (addresshashfull[i] != confbytes[i + 6])
                    {
                        MessageBox.Show("This passphrase is wrong or does not belong to this confirmation code.", "Invalid passphrase", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                        return;
                    }
                }

                confirmIsValid(generatedaddress.AddressBase58);
            } catch {
                // Might throw an exception - not every 256-bit integer is a valid X coordinate
                MessageBox.Show("This passphrase is wrong or does not belong to this confirmation code.", "Invalid passphrase", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }
        }
        public override async Task PairAsync(string ipAddress, TextBox outputTextBox)
        {
            // Create SHA256 hash digest. This is not supported by server version < 7
            // (need to use SHA1 for those cases) but that doesn't really matter right now.
            IDigest hashAlgorithm  = new Sha256Digest();
            int     hashDigestSize = hashAlgorithm.GetDigestSize();

            // Create and salt pin
            byte[] salt = this.GenerateRandomBytes(16);
            string pin  = GenerateRandomPin();

            byte[] saltAndPin = SaltPin(salt, pin);

            // Asymmetric key pair
            RsaKeyPairGenerator keyPairGenerator = new RsaKeyPairGenerator();

            keyPairGenerator.Init(new KeyGenerationParameters(this.SecureRandom, 2048));
            AsymmetricCipherKeyPair keyPair = keyPairGenerator.GenerateKeyPair();

            // Certificate issuer and name
            X509Name name = new X509Name("CN=NVIDIA GameStream Client");

            // Certificate serial number
            byte[]     serialBytes = this.GenerateRandomBytes(8);
            BigInteger serial      = new BigInteger(serialBytes).Abs();

            // Expires in 20 years
            DateTime now        = DateTime.UtcNow;
            DateTime expiration = now.AddYears(20);

            X509V3CertificateGenerator generator = new X509V3CertificateGenerator();

            generator.SetSubjectDN(name);
            generator.SetIssuerDN(name);
            generator.SetSerialNumber(serial);
            generator.SetNotBefore(now);
            generator.SetNotAfter(expiration);
            generator.SetPublicKey(keyPair.Public);

            BouncyCastleX509Certificate certificate =
                generator.Generate(
                    new Asn1SignatureFactory("SHA1WithRSA", keyPair.Private));

            // Create PKCS12 certificate bytes.
            Pkcs12Store          store            = new Pkcs12Store();
            X509CertificateEntry certificateEntry = new X509CertificateEntry(certificate);
            string friendlyName = "Moonlight Xbox";
            string password     = "******";

            store.SetCertificateEntry(friendlyName, certificateEntry);
            store.SetKeyEntry(
                friendlyName,
                new AsymmetricKeyEntry(keyPair.Private),
                new X509CertificateEntry[] { certificateEntry });
            string pfxData;

            using (MemoryStream memoryStream = new MemoryStream(512))
            {
                store.Save(memoryStream, password.ToCharArray(), this.SecureRandom);
                pfxData = CryptographicBuffer.EncodeToBase64String(memoryStream.ToArray().AsBuffer());
            }

            await CertificateEnrollmentManager.ImportPfxDataAsync(
                pfxData,
                password,
                ExportOption.NotExportable,
                KeyProtectionLevel.NoConsent,
                InstallOptions.DeleteExpired,
                friendlyName);

            // Read the UWP cert from the cert store
            Certificate uwpCertificate =
                (await CertificateStores.FindAllAsync(
                     new CertificateQuery {
                FriendlyName = friendlyName
            }))[0];

            string keyString;

            using (StringWriter keyWriter = new StringWriter())
            {
                PemWriter pemWriter = new PemWriter(keyWriter);
                pemWriter.WriteObject(keyPair);
                keyString = keyWriter.ToString();

                // Line endings must be UNIX style for GFE to accept the certificate.
                keyString = keyString.Replace(Environment.NewLine, "\n");
            }

            string certString;

            using (StringWriter certWriter = new StringWriter())
            {
                PemWriter pemWriter = new PemWriter(certWriter);
                pemWriter.WriteObject(certificate);
                certString = certWriter.ToString();

                // Line endings must be UNIX style for GFE to accept the certificate.
                certString = certString.Replace(Environment.NewLine, "\n");
            }

            byte[] pemCertBytes = Encoding.UTF8.GetBytes(certString);
            byte[] uniqueId     = GenerateRandomBytes(8);

            // Create the HTTP client.
            HttpBaseProtocolFilter filter = new HttpBaseProtocolFilter();

            filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.Untrusted);
            filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.InvalidName);
            filter.ClientCertificate = uwpCertificate;

            HttpClient httpClient = new HttpClient(filter);

            // Unpair before doing anything else in this test app.
            string uriString =
                string.Format(
                    "http://{0}:47989/unpair?uniqueid={1}&uuid={2}",
                    ipAddress,
                    BytesToHex(uniqueId),
                    Guid.NewGuid().ToString("N"));

            using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, new Uri(uriString)))
            {
                using (HttpResponseMessage response = await httpClient.SendRequestAsync(request))
                {
                    outputTextBox.Text = $"Unpair status code: {response.StatusCode}\n";
                    string responseContent = await response.Content.ReadAsStringAsync();

                    outputTextBox.Text += responseContent + "\n";
                }
            }

            await Task.Delay(2000);

            outputTextBox.Text = $"Enter pin: {pin}";

            // Get server certificate.
            // TODO: Call should have no timeout because it requires the user to enter a pin.
            PairResponse pairResponse = null;

            uriString =
                string.Format(
                    "http://{0}:47989/pair?uniqueid={1}&uuid={2}&devicename=roth&updateState=1&phrase=getservercert&salt={3}&clientcert={4}",
                    ipAddress,
                    BytesToHex(uniqueId),
                    Guid.NewGuid().ToString("N"),
                    BytesToHex(salt),
                    BytesToHex(pemCertBytes));
            using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, new Uri(uriString)))
            {
                using (HttpResponseMessage response = await httpClient.SendRequestAsync(request))
                {
                    outputTextBox.Text = $"Get server cert status code: {response.StatusCode}\n";
                    string responseContent = await response.Content.ReadAsStringAsync();

                    outputTextBox.Text += responseContent + "\n";
                    using (StringReader reader = new StringReader(responseContent))
                    {
                        XmlSerializer serializer = new XmlSerializer(typeof(PairResponse));
                        pairResponse = serializer.Deserialize(new StringReader(responseContent)) as PairResponse;
                    }
                }
            }

            if (pairResponse == null || pairResponse.Paired != 1)
            {
                outputTextBox.Text += "Pairing failed.\n";
                return;
            }

            if (string.IsNullOrEmpty(pairResponse.PlainCert))
            {
                outputTextBox.Text += "Pairing already in progress.\n";
                return;
            }

            // Parse server certificate
            byte[] serverCertBytes = HexToBytes(pairResponse.PlainCert);
            BouncyCastleX509Certificate serverCertificate = new X509CertificateParser().ReadCertificate(serverCertBytes);

            // Hash the salt and pin and use it to generate an AES key.
            byte[]            hashedSaltAndPin = HashData(hashAlgorithm, saltAndPin);
            ICipherParameters aesKey           = GenerateCipherKey(hashedSaltAndPin);

            // Generate a random challenge and encrypt it using AES.
            byte[] challenge          = GenerateRandomBytes(16);
            byte[] encryptedChallenge = DoAesCipher(true, aesKey, challenge);

            await Task.Delay(2000);

            // Send the encrypted challenge to the server.
            // TODO: Call should have a timeout.
            uriString =
                string.Format(
                    "http://{0}:47989/pair?uniqueid={1}&uuid={2}&devicename=roth&updateState=1&clientchallenge={3}",
                    ipAddress,
                    BytesToHex(uniqueId),
                    Guid.NewGuid().ToString("N"),
                    BytesToHex(encryptedChallenge));
            using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, new Uri(uriString)))
            {
                using (HttpResponseMessage response = await httpClient.SendRequestAsync(request))
                {
                    outputTextBox.Text = $"Send challenge status code: {response.StatusCode}\n";
                    string responseContent = await response.Content.ReadAsStringAsync();

                    outputTextBox.Text += responseContent + "\n";
                    using (StringReader reader = new StringReader(responseContent))
                    {
                        XmlSerializer serializer = new XmlSerializer(typeof(PairResponse));
                        pairResponse = serializer.Deserialize(new StringReader(responseContent)) as PairResponse;
                    }
                }
            }

            if (pairResponse == null || pairResponse.Paired != 1)
            {
                outputTextBox.Text += "Pairing failed.\n";
                return;
            }

            // Decode the server's response and subsequent challenge.
            byte[] encryptedServerChallengeResponse = HexToBytes(pairResponse.ChallengeResponse);
            byte[] decryptedServerChallengeResponse = DoAesCipher(false, aesKey, encryptedServerChallengeResponse);

            byte[] serverResponse  = new byte[hashDigestSize];
            byte[] serverChallenge = new byte[16];
            Array.Copy(decryptedServerChallengeResponse, serverResponse, hashDigestSize);
            Array.Copy(decryptedServerChallengeResponse, hashDigestSize, serverChallenge, 0, 16);

            // Using another 16 byte secret, compute a challenge response hash using the secret,
            // our certificate signature, and the challenge.
            byte[] clientSecret          = GenerateRandomBytes(16);
            byte[] challengeResponseHash =
                HashData(
                    hashAlgorithm,
                    ConcatenateByteArrays(serverChallenge, certificate.GetSignature(), clientSecret));
            byte[] encryptedChallengeResponse = DoAesCipher(true, aesKey, challengeResponseHash);

            await Task.Delay(2000);

            // Send the challenge response to the server.
            // TODO: Call should have a timeout.
            uriString =
                string.Format(
                    "http://{0}:47989/pair?uniqueid={1}&uuid={2}&devicename=roth&updateState=1&serverchallengeresp={3}",
                    ipAddress,
                    BytesToHex(uniqueId),
                    Guid.NewGuid().ToString("N"),
                    BytesToHex(encryptedChallengeResponse));
            using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, new Uri(uriString)))
            {
                using (HttpResponseMessage response = await httpClient.SendRequestAsync(request))
                {
                    outputTextBox.Text = $"Send challenge response status code: {response.StatusCode}\n";
                    string responseContent = await response.Content.ReadAsStringAsync();

                    outputTextBox.Text += responseContent + "\n";
                    using (StringReader reader = new StringReader(responseContent))
                    {
                        XmlSerializer serializer = new XmlSerializer(typeof(PairResponse));
                        pairResponse = serializer.Deserialize(new StringReader(responseContent)) as PairResponse;
                    }
                }
            }

            if (pairResponse == null || pairResponse.Paired != 1)
            {
                outputTextBox.Text += "Pairing failed.\n";
                // TODO: Unpair here by calling http://<blah>/unpair?uniqueid={1}&uuid={2}.
                return;
            }

            // Get the server's signed secret.
            byte[] serverSecretResponse = HexToBytes(pairResponse.PairingSecret);
            byte[] serverSecret         = new byte[16];
            byte[] serverSignature      = new byte[256];
            Array.Copy(serverSecretResponse, serverSecret, serverSecret.Length);
            Array.Copy(serverSecretResponse, serverSecret.Length, serverSignature, 0, serverSignature.Length);

            if (!VerifySignature(serverSecret, serverSignature, serverCertificate.GetPublicKey()))
            {
                outputTextBox.Text += "Pairing failed.\n";
                // TODO: Unpair as above.
                return;
            }

            // Ensure the server challenge matched what we expected (the PIN was correct).
            byte[] serverChallengeResponseHash =
                HashData(
                    hashAlgorithm,
                    ConcatenateByteArrays(
                        challenge,
                        serverCertificate.GetSignature(),
                        serverSecret));
            if (!serverChallengeResponseHash.SequenceEqual(serverResponse))
            {
                outputTextBox.Text += "Pairing failed due to wrong pin.\n";
                // TODO: Unpair as above.
                return;
            }

            await Task.Delay(2000);

            // Send the server our signed secret
            // TODO: Call should have a timeout.
            byte[] signedSecret        = SignData(clientSecret, keyPair.Private);
            byte[] clientPairingSecret =
                ConcatenateByteArrays(
                    clientSecret,
                    signedSecret);
            uriString =
                string.Format(
                    "http://{0}:47989/pair?uniqueid={1}&uuid={2}&devicename=roth&updateState=1&clientpairingsecret={3}",
                    ipAddress,
                    BytesToHex(uniqueId),
                    Guid.NewGuid().ToString("N"),
                    BytesToHex(clientPairingSecret));
            using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, new Uri(uriString)))
            {
                using (HttpResponseMessage response = await httpClient.SendRequestAsync(request))
                {
                    outputTextBox.Text = $"Send client pairing secret status code: {response.StatusCode}\n";
                    string responseContent = await response.Content.ReadAsStringAsync();

                    outputTextBox.Text += responseContent + "\n";
                    using (StringReader reader = new StringReader(responseContent))
                    {
                        XmlSerializer serializer = new XmlSerializer(typeof(PairResponse));
                        pairResponse = serializer.Deserialize(new StringReader(responseContent)) as PairResponse;
                    }
                }
            }

            if (pairResponse == null || pairResponse.Paired != 1)
            {
                outputTextBox.Text += "Pairing failed.\n";
                // TODO: Unpair as above.
                return;
            }

            await Task.Delay(2000);

            // Do the initial challenge (seems neccessary for us to show as paired).
            // TODO: Call should have a timeout.
            uriString =
                string.Format(
                    "https://{0}:47984/pair?uniqueid={1}&uuid={2}&devicename=roth&updateState=1&phrase=pairchallenge",
                    ipAddress,
                    BytesToHex(uniqueId),
                    Guid.NewGuid().ToString("N"));
            using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, new Uri(uriString)))
            {
                using (HttpResponseMessage response = await httpClient.SendRequestAsync(request))
                {
                    outputTextBox.Text = $"Send pair challenge status code: {response.StatusCode}\n";
                    string responseContent = await response.Content.ReadAsStringAsync();

                    outputTextBox.Text += responseContent + "\n";
                    using (StringReader reader = new StringReader(responseContent))
                    {
                        XmlSerializer serializer = new XmlSerializer(typeof(PairResponse));
                        pairResponse = serializer.Deserialize(new StringReader(responseContent)) as PairResponse;
                    }
                }
            }

            if (pairResponse == null || pairResponse.Paired != 1)
            {
                outputTextBox.Text += "Pairing failed.\n";
                // TODO: Unpair as above.
                return;
            }

            await Task.Delay(2000);

            outputTextBox.Text = "Pairing succeeded!\n";
        }
Beispiel #24
0
        public ITestResult Perform()
        {
            IDigest digest = new Sha256Digest();

            byte[] resBuf = new byte[digest.GetDigestSize()];
            string resStr;

            //
            // test 1
            //
            digest.DoFinal(resBuf, 0);

            resStr = Hex.ToHexString(resBuf);
            if (!resVec1.Equals(resStr))
            {
                return(new SimpleTestResult(false,
                                            "SHA-256 failing standard vector test 1"
                                            + SimpleTest.NewLine
                                            + "    expected: " + resVec1
                                            + SimpleTest.NewLine
                                            + "    got     : " + resStr));
            }

            //
            // test 2
            //
            byte[] bytes = Hex.Decode(testVec2);

            digest.BlockUpdate(bytes, 0, bytes.Length);

            digest.DoFinal(resBuf, 0);

            resStr = Hex.ToHexString(resBuf);
            if (!resVec2.Equals(resStr))
            {
                return(new SimpleTestResult(false,
                                            "SHA-256 failing standard vector test 2"
                                            + SimpleTest.NewLine
                                            + "    expected: " + resVec2
                                            + SimpleTest.NewLine
                                            + "    got     : " + resStr));
            }

            //
            // test 3
            //
            bytes = Hex.Decode(testVec3);

            digest.BlockUpdate(bytes, 0, bytes.Length);

            digest.DoFinal(resBuf, 0);

            resStr = Hex.ToHexString(resBuf);
            if (!resVec3.Equals(resStr))
            {
                return(new SimpleTestResult(false,
                                            "SHA-256 failing standard vector test 3"
                                            + SimpleTest.NewLine
                                            + "    expected: " + resVec3
                                            + SimpleTest.NewLine
                                            + "    got     : " + resStr));
            }

            //
            // test 4
            //
            bytes = Hex.Decode(testVec4);

            digest.BlockUpdate(bytes, 0, bytes.Length);

            digest.DoFinal(resBuf, 0);

            resStr = Hex.ToHexString(resBuf);
            if (!resVec4.Equals(resStr))
            {
                return(new SimpleTestResult(false,
                                            "SHA-256 failing standard vector test 4"
                                            + SimpleTest.NewLine
                                            + "    expected: " + resVec4
                                            + SimpleTest.NewLine
                                            + "    got     : " + resStr));
            }

            //
            // test 5
            //
            bytes = Hex.Decode(testVec4);

            digest.BlockUpdate(bytes, 0, bytes.Length / 2);

            // clone the IDigest
            IDigest d = new Sha256Digest((Sha256Digest)digest);

            digest.BlockUpdate(bytes, bytes.Length / 2, bytes.Length - bytes.Length / 2);
            digest.DoFinal(resBuf, 0);

            resStr = Hex.ToHexString(resBuf);
            if (!resVec4.Equals(resStr))
            {
                return(new SimpleTestResult(false,
                                            "SHA256 failing standard vector test 5"
                                            + SimpleTest.NewLine
                                            + "    expected: " + resVec4
                                            + SimpleTest.NewLine
                                            + "    got     : " + resStr));
            }

            d.BlockUpdate(bytes, bytes.Length / 2, bytes.Length - bytes.Length / 2);
            d.DoFinal(resBuf, 0);

            resStr = Hex.ToHexString(resBuf);
            if (!resVec4.Equals(resStr))
            {
                return(new SimpleTestResult(false,
                                            "SHA256 failing standard vector test 5"
                                            + SimpleTest.NewLine
                                            + "    expected: " + resVec4
                                            + SimpleTest.NewLine
                                            + "    got     : " + resStr));
            }

            // test 6
            bytes = Hex.Decode(testVec5);
            for (int i = 0; i < 100000; i++)
            {
                digest.BlockUpdate(bytes, 0, bytes.Length);
            }
            digest.DoFinal(resBuf, 0);

            resStr = Hex.ToHexString(resBuf);
            if (!resVec5.Equals(resStr))
            {
                return(new SimpleTestResult(false,
                                            "SHA-256 failing standard vector test 5"
                                            + SimpleTest.NewLine
                                            + "    expected: " + resVec5
                                            + SimpleTest.NewLine
                                            + "    got     : " + resStr));
            }

            return(new SimpleTestResult(true, Name + ": Okay"));
        }
Beispiel #25
0
        private string salt = "wefdhwfkhjwefopiwjdfldkdsfjndkljf"; // initial salt replaced at runtime

        private void GenerateAddresses()
        {
            string       b58       = "23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
            int          b58len    = b58.Length;
            Sha256Digest bcsha256a = new Sha256Digest();
            Sha256Digest bcsha256b = new Sha256Digest();

            string shacode = "";


            SecureRandom sr  = new SecureRandom();
            int          dec = 0;

            List <string> myaddresses = new List <string>();
            Dictionary <string, string> myprivkeys = new Dictionary <string, string>();

            for (int ji = 0; ji < 100000000; ji++)
            {
                byte[] poop = Util.ComputeSha256(salt + ji.ToString());

                byte[] ahash = null;
                do
                {
                    // Get 'S' + 21 random base58 characters, where sha256(result + '?') starts with the byte 00 (1 in 256 possibilities)
                    shacode = "S";
                    for (int i = 0; i < 29; i++)
                    {
                        long x = sr.NextLong() & long.MaxValue;
                        x += poop[i];
                        long x58 = x % b58len;
                        shacode += b58.Substring((int)x58, 1);
                    }
                    string shacodeq = shacode + "?";
                    ahash = Util.ComputeSha256(Encoding.ASCII.GetBytes(shacodeq));

                    if (ahash[0] == 0)
                    {
                        break;
                    }

                    Application.DoEvents();
                } while (true);


                string pubhex  = Util.PrivHexToPubHex(Util.ByteArrayToString(Util.ComputeSha256(shacode)));
                string pubhash = Util.PubHexToPubHash(pubhex);
                string address = Util.PubHashToAddress(pubhash, "Dogecoin");


                pubhex = pubhex.Replace(" ", "");

                lock (LockObject) {
                    using (StreamWriter sw1 = new StreamWriter("privkeys3.txt", true)) {
                        sw1.WriteLine("\"" + address + "\",\"" + shacode + "\",\"" + pubhex + "\"");
                        sw1.Close();
                    }


                    using (StreamWriter sw1 = new StreamWriter("addresses3.txt", true)) {
                        sw1.WriteLine("\"" + address + "\",\"" + pubhex + "\"");
                        sw1.Close();
                    }
                }

                Debug.WriteLine(shacode + "=" + address);

                /*
                 * myaddresses.Add(address);
                 * myprivkeys.Add(address, shacode);
                 * dec++;
                 * if (dec == 1000) {
                 *  dec = 0;
                 *  Application.DoEvents();
                 * }
                 * */
            }
        }
        protected byte[] HMAC(CBORObject alg, byte[] K)
        {
            int     cbitKey;
            int     cbResult;
            IDigest digest;

            if (alg.Type == CBORType.TextString)
            {
                switch (alg.AsString())
                {
                default:
                    throw new Exception("Unrecognized algorithm");
                }
            }
            else if (alg.Type == CBORType.Number)
            {
                switch ((AlgorithmValuesInt)alg.AsInt32())
                {
                case AlgorithmValuesInt.HMAC_SHA_256:
                    cbitKey  = 256;
                    cbResult = 256 / 8;
                    digest   = new Sha256Digest();
                    break;

                case AlgorithmValuesInt.HMAC_SHA_256_64:
                    cbitKey  = 256;
                    digest   = new Sha256Digest();
                    cbResult = 64 / 8;
                    break;

                case AlgorithmValuesInt.HMAC_SHA_384:
                    cbitKey  = 384;
                    digest   = new Sha384Digest();
                    cbResult = cbitKey / 8;
                    break;

                case AlgorithmValuesInt.HMAC_SHA_512:
                    cbitKey  = 512;
                    digest   = new Sha512Digest();
                    cbResult = cbitKey / 8;
                    break;

                default:
                    throw new CoseException("Unknown or unsupported algorithm");
                }
            }
            else
            {
                throw new CoseException("Algorithm incorrectly encoded");
            }

            if (K == null)
            {
                throw new CoseException("No Key value");
            }

            HMac         hmac = new HMac(digest);
            KeyParameter key  = new KeyParameter(K);

            byte[] resBuf = new byte[hmac.GetMacSize()];

            byte[] toDigest = BuildContentBytes();

            hmac.Init(key);
            hmac.BlockUpdate(toDigest, 0, toDigest.Length);
            hmac.DoFinal(resBuf, 0);

            byte[] rgbOut = new byte[cbResult];
            Array.Copy(resBuf, rgbOut, cbResult);

            return(rgbOut);
        }
Beispiel #27
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);
             */
        }
Beispiel #28
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);
        }
Beispiel #29
0
        public void Verify(Key key, SignMessage msg)
        {
            string alg = FindAttr("alg", msg).AsString();

            IDigest digest;
            IDigest digest2;

            switch (alg)
            {
            case "RS256":
            case "ES256":
            case "PS256":
            case "HS256":
                digest  = new Sha256Digest();
                digest2 = new Sha256Digest();
                break;

            case "RS384":
            case "ES384":
            case "PS384":
            case "HS384":
                digest  = new Sha384Digest();
                digest2 = new Sha384Digest();
                break;

            case "RS512":
            case "ES512":
            case "PS512":
            case "HS512":
                digest  = new Sha512Digest();
                digest2 = new Sha512Digest();
                break;

            case "EdDSA":
                digest  = null;
                digest2 = null;
                break;

            default:
                throw new JOSE_Exception("Unknown signature algorithm");
            }



            switch (alg)
            {
            case "RS256":
            case "RS384":
            case "RS512": {
                if (key.AsString("kty") != "RSA")
                {
                    throw new JOSE_Exception("Wrong Key");
                }
                RsaDigestSigner  signer = new RsaDigestSigner(digest);
                RsaKeyParameters pub    = new RsaKeyParameters(false, key.AsBigInteger("n"), key.AsBigInteger("e"));

                signer.Init(false, pub);
                signer.BlockUpdate(protectedB64, 0, protectedB64.Length);
                signer.BlockUpdate(rgbDot, 0, 1);
                signer.BlockUpdate(msg.payloadB64, 0, msg.payloadB64.Length);
                if (!signer.VerifySignature(signature))
                {
                    throw new JOSE_Exception("Message failed to verify");
                }
            }
            break;

            case "PS256":
            case "PS384":
            case "PS512": {
                PssSigner        signer = new PssSigner(new RsaEngine(), digest, digest2, digest.GetDigestSize());
                RsaKeyParameters pub    = new RsaKeyParameters(false, key.AsBigInteger("n"), key.AsBigInteger("e"));

                signer.Init(false, pub);
                signer.BlockUpdate(protectedB64, 0, protectedB64.Length);
                signer.BlockUpdate(rgbDot, 0, 1);
                signer.BlockUpdate(msg.payloadB64, 0, msg.payloadB64.Length);
                if (!signer.VerifySignature(signature))
                {
                    throw new JOSE_Exception("Message failed to verify");
                }
            }

            break;

            case "ES256":
            case "ES384":
            case "ES512": {
                if (key.AsString("kty") != "EC")
                {
                    throw new JOSE_Exception("Wrong Key Type");
                }
                X9ECParameters     p          = NistNamedCurves.GetByName(key.AsString("crv"));
                ECDomainParameters parameters = new ECDomainParameters(p.Curve, p.G, p.N, p.H);
                ECPoint            point      = p.Curve.CreatePoint(key.AsBigInteger("x"
                                                                                     ), key.AsBigInteger("y"));
                ECPublicKeyParameters pubKey = new ECPublicKeyParameters(point, parameters);

                ECDsaSigner ecdsa = new ECDsaSigner();
                ecdsa.Init(false, pubKey);

                digest.BlockUpdate(protectedB64, 0, protectedB64.Length);
                digest.BlockUpdate(rgbDot, 0, rgbDot.Length);
                digest.BlockUpdate(msg.payloadB64, 0, msg.payloadB64.Length);
                byte[] o1 = new byte[digest.GetDigestSize()];
                digest.DoFinal(o1, 0);

                BigInteger r = new BigInteger(1, signature, 0, signature.Length / 2);
                BigInteger s = new BigInteger(1, signature, signature.Length / 2, signature.Length / 2);

                if (!ecdsa.VerifySignature(o1, r, s))
                {
                    throw new JOSE_Exception("Signature did not validate");
                }
            }
            break;

            case "HS256":
            case "HS384":
            case "HS512": {
                HMac         hmac = new HMac(digest);
                KeyParameter K    = new KeyParameter(Message.base64urldecode(key.AsString("k")));
                hmac.Init(K);
                hmac.BlockUpdate(protectedB64, 0, protectedB64.Length);
                hmac.BlockUpdate(rgbDot, 0, rgbDot.Length);
                hmac.BlockUpdate(msg.payloadB64, 0, msg.payloadB64.Length);

                byte[] resBuf = new byte[hmac.GetMacSize()];
                hmac.DoFinal(resBuf, 0);

                bool fVerify = true;
                for (int i = 0; i < resBuf.Length; i++)
                {
                    if (resBuf[i] != signature[i])
                    {
                        fVerify = false;
                    }
                }

                if (!fVerify)
                {
                    throw new JOSE_Exception("Signature did not validte");
                }
            }
            break;

            case "EdDSA": {
                ISigner eddsa;
                if (key.AsString("kty") != "OKP")
                {
                    throw new JOSE_Exception("Wrong Key Type");
                }
                switch (key.AsString("crv"))
                {
                case "Ed25519": {
                    Ed25519PublicKeyParameters privKey =
                        new Ed25519PublicKeyParameters(key.AsBytes("X"), 0);
                    eddsa = new Ed25519Signer();
                    eddsa.Init(false, privKey);

                    byte[] toVerify = new byte[protectedB64.Length + rgbDot.Length + msg.payloadB64.Length];
                    Array.Copy(protectedB64, 0, toVerify, 0, protectedB64.Length);
                    Array.Copy(rgbDot, 0, toVerify, protectedB64.Length, rgbDot.Length);
                    Array.Copy(msg.payloadB64, 0, toVerify, protectedB64.Length + rgbDot.Length, msg.payloadB64.Length);

                    eddsa.BlockUpdate(toVerify, 0, toVerify.Length);
                    if (!eddsa.VerifySignature(signature))
                    {
                        throw new JOSE_Exception("Signature did not validate");
                    }

                    break;
                }

                default:
                    throw new JOSE_Exception("Unknown algorithm");
                }

                break;
            }

            default:
                throw new JOSE_Exception("Unknown algorithm");
            }
        }
Beispiel #30
0
        private byte[] Sign(byte[] bytesToBeSigned)
        {
            string alg = null; // Get the set algorithm or infer one

            try {
                alg = FindAttribute("alg").AsString();
            }
            catch (Exception) {
                ;
            }

            if (alg == null)
            {
                switch (keyToSign.AsString("kty"))
                {
                case "RSA":
                    alg = "PS256";
                    break;

                case "EC":
                    switch (keyToSign.AsString("crv"))
                    {
                    case "P-256":
                        alg = "ES256";
                        break;

                    case "P-384":
                        alg = "ES384";
                        break;

                    case "P-521":
                        alg = "ES512";
                        break;

                    default:
                        throw new JOSE_Exception("Unknown curve");
                    }

                    break;

                default:
                    throw new JOSE_Exception("Unknown or unsupported key type " + keyToSign.AsString("kty"));
                }

                objUnprotected.Add("alg", alg);
            }

            IDigest digest;
            IDigest digest2;

            switch (alg)
            {
            case "RS256":
            case "ES256":
            case "PS256":
            case "HS256":
                digest  = new Sha256Digest();
                digest2 = new Sha256Digest();
                break;

            case "RS384":
            case "ES384":
            case "PS384":
            case "HS384":
                digest  = new Sha384Digest();
                digest2 = new Sha384Digest();
                break;

            case "RS512":
            case "ES512":
            case "PS512":
            case "HS512":
                digest  = new Sha512Digest();
                digest2 = new Sha512Digest();
                break;

            case "EdDSA":
                digest  = null;
                digest2 = null;
                break;

            default:
                throw new JOSE_Exception("Unknown signature algorithm");
            }


            switch (alg)
            {
            case "RS256":
            case "RS384":
            case "RS512": {
                RsaDigestSigner  signer = new RsaDigestSigner(digest);
                RsaKeyParameters prv    = new RsaPrivateCrtKeyParameters(ConvertBigNum(keyToSign.AsBytes("n")),
                                                                         ConvertBigNum(keyToSign.AsBytes("e")),
                                                                         ConvertBigNum(keyToSign.AsBytes("d")),
                                                                         ConvertBigNum(keyToSign.AsBytes("p")),
                                                                         ConvertBigNum(keyToSign.AsBytes("q")),
                                                                         ConvertBigNum(keyToSign.AsBytes("dp")),
                                                                         ConvertBigNum(keyToSign.AsBytes("dq")),
                                                                         ConvertBigNum(keyToSign.AsBytes("qi")));

                signer.Init(true, prv);
                signer.BlockUpdate(bytesToBeSigned, 0, bytesToBeSigned.Length);
                return(signer.GenerateSignature());
            }

            case "PS256":
            case "PS384":
            case "PS512": {
                PssSigner signer = new PssSigner(new RsaEngine(), digest, digest2, digest.GetDigestSize());

                RsaKeyParameters prv = new RsaPrivateCrtKeyParameters(ConvertBigNum(keyToSign.AsBytes("n")),
                                                                      ConvertBigNum(keyToSign.AsBytes("e")),
                                                                      ConvertBigNum(keyToSign.AsBytes("d")),
                                                                      ConvertBigNum(keyToSign.AsBytes("p")),
                                                                      ConvertBigNum(keyToSign.AsBytes("q")),
                                                                      ConvertBigNum(keyToSign.AsBytes("dp")),
                                                                      ConvertBigNum(keyToSign.AsBytes("dq")),
                                                                      ConvertBigNum(keyToSign.AsBytes("qi")));
                ParametersWithRandom rnd = new ParametersWithRandom(prv, Message.s_PRNG);

                signer.Init(true, rnd);
                signer.BlockUpdate(bytesToBeSigned, 0, bytesToBeSigned.Length);
                return(signer.GenerateSignature());
            }

            case "ES256":
            case "ES384":
            case "ES512": {
                X9ECParameters         p          = NistNamedCurves.GetByName(keyToSign.AsString("crv"));
                ECDomainParameters     parameters = new ECDomainParameters(p.Curve, p.G, p.N, p.H);
                ECPrivateKeyParameters privKey    =
                    new ECPrivateKeyParameters("ECDSA", ConvertBigNum(keyToSign.AsBytes("d")), parameters);
                ParametersWithRandom param = new ParametersWithRandom(privKey, Message.s_PRNG);

                ECDsaSigner ecdsa = new ECDsaSigner(new HMacDsaKCalculator(new Sha256Digest()));
                ecdsa.Init(true, param);

                BigInteger[] sig  = ecdsa.GenerateSignature(bytesToBeSigned);
                byte[]       r    = sig[0].ToByteArrayUnsigned();
                byte[]       s    = sig[1].ToByteArrayUnsigned();
                byte[]       sigs = new byte[r.Length + s.Length];
                Array.Copy(r, sigs, r.Length);
                Array.Copy(s, 0, sigs, r.Length, s.Length);

                return(sigs);
            }

            case "HS256":
            case "HS384":
            case "HS512": {
                HMac hmac = new HMac(digest);

                KeyParameter key    = new KeyParameter(keyToSign.AsBytes("k"));
                byte[]       resBuf = new byte[hmac.GetMacSize()];

                hmac.Init(key);
                hmac.BlockUpdate(bytesToBeSigned, 0, bytesToBeSigned.Length);
                hmac.DoFinal(resBuf, 0);

                return(resBuf);
            }

            case "EdDSA":
                switch (keyToSign.AsString("crv"))
                {
                case "Ed25519": {
                    ISigner eddsa;
                    Ed25519PrivateKeyParameters privKey =
                        new Ed25519PrivateKeyParameters(keyToSign.AsBytes("d"), 0);
                    eddsa = new Ed25519Signer();
                    eddsa.Init(true, privKey);


                    eddsa.BlockUpdate(bytesToBeSigned, 0, bytesToBeSigned.Length);

                    return(eddsa.GenerateSignature());
                }
                }

                break;
            }

            return(null);
        }