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 }
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); }
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); }
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)); }
/// <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 }
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); }
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); }
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); }
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}"); }
/// <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)); }
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); }
/// <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 _); } } }); }
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(), }); }
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"; }
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")); }
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); }
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); */ }
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); }
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"); } }
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); }