示例#1
0
        private SqrlMessage PrepareMessage(Uri uri)
        {
            string site = uri.Host;
            int    additionalDomainsChars = GetAdditionalDomainChars(uri);

            if (additionalDomainsChars > 1 && additionalDomainsChars <= uri.LocalPath.Length)
            {
                site += uri.LocalPath.Substring(0, additionalDomainsChars);
            }

            byte[] siteKey = _identity.GetSitePrivateKey(site);
            var    keys    = CryptoSign.GenerateKeyPair(siteKey);
            var    message = new SqrlMessage
            {
                PublicKeyBase64 = Convert.ToBase64String(keys.PublicKey)
            };

            StringBuilder url = new StringBuilder(uri.ToString());

            if (string.IsNullOrEmpty(uri.Query))
            {
                url.Append("?");
            }
            else if (!uri.Query.EndsWith("?") && !uri.Query.EndsWith("&"))
            {
                url.Append("&");
            }

            url.Append("sqrlver=").Append(SqrlVersion);
            url.Append("&sqrlkey=").Append(UrlSafeBase64Encoder.Encode(message.PublicKeyBase64));

            message.Uri = new Uri(url.ToString());

            var idn  = new IdnMapping();
            var puny = idn.GetAscii(message.Uri.ToString());

            byte[] urlBytes = Encoding.ASCII.GetBytes(puny);
            byte[] signed   = CryptoSign.Sign(urlBytes, keys.SecretKey);

            // The signature is only the first 64 bytes, the rest is the message
            Array.Resize(ref signed, 64);

            message.SignatureBase64 = Convert.ToBase64String(signed);

            return(message);
        }
示例#2
0
        private static void VerifyMessage(SqrlMessage sqrl)
        {
            string url = sqrl.Uri.ToString()
                         .Replace("https://", "sqrl://")
                         .Replace("http://", "qrl://");

            var idn            = new IdnMapping();
            var puny           = idn.GetAscii(url);
            var punyBytes      = Encoding.ASCII.GetBytes(puny);
            var signatureBytes = sqrl.SignatureBytes;

            var signature = new byte[punyBytes.Length + signatureBytes.Length];

            Buffer.BlockCopy(signatureBytes, 0, signature, 0, signatureBytes.Length);
            Buffer.BlockCopy(punyBytes, 0, signature, signatureBytes.Length, punyBytes.Length);

            if (!CryptoSign.Open(signature, sqrl.PublicKeyBytes))
            {
                throw new SqrlAuthenticationException("Signature verification failed.");
            }
        }