private void GenerateKeys(string seed)
        {
            // generate the RSA keypair for the address
            AsymmetricCipherKeyPair rsaKeyPair = WalletController.GetRSAKeyPairFromSeed(seed);

            RsaKeyParameters rsaPublicKey = rsaKeyPair.Public as RsaKeyParameters;
            RsaPublicKey     pbk          = new RsaPublicKey()
            {
                Exponent = rsaPublicKey.Exponent.ToByteArrayUnsigned(),
                Modulus  = rsaPublicKey.Modulus.ToByteArrayUnsigned()
            };

            RsaPrivateCrtKeyParameters rsaPrivateKey = rsaKeyPair.Private as RsaPrivateCrtKeyParameters;
            RsaPrivateKey prk = new RsaPrivateKey()
            {
                DP             = rsaPrivateKey.DP.ToByteArrayUnsigned(),
                DQ             = rsaPrivateKey.DQ.ToByteArrayUnsigned(),
                Exponent       = rsaPrivateKey.Exponent.ToByteArrayUnsigned(),
                Modulus        = rsaPrivateKey.Modulus.ToByteArrayUnsigned(),
                P              = rsaPrivateKey.P.ToByteArrayUnsigned(),
                PublicExponent = rsaPrivateKey.PublicExponent.ToByteArrayUnsigned(),
                Q              = rsaPrivateKey.Q.ToByteArrayUnsigned(),
                QInv           = rsaPrivateKey.QInv.ToByteArrayUnsigned()
            };

            this._testOutputHelper.WriteLine($"Public key: {pbk.ToHex()}");
            this._testOutputHelper.WriteLine($"Private key: {prk.ToHex()}");
        }
Esempio n. 2
0
        public IActionResult CreateReviewerAddressAsync([FromBody] CreateReviewerAddressRequest request)
        {
            Guard.NotNull(request, nameof(request));

            // checks the request is valid
            if (!this.ModelState.IsValid)
            {
                return(ModelStateErrors.BuildErrorResponse(this.ModelState));
            }

            try
            {
                // calculate the Manager password hash
                byte[] binaryPassword = System.Text.Encoding.ASCII.GetBytes(request.RsaPassword);

                Org.BouncyCastle.Crypto.Digests.Sha512Digest sha = new Org.BouncyCastle.Crypto.Digests.Sha512Digest();
                sha.BlockUpdate(binaryPassword, 0, binaryPassword.Length);

                byte[] shaOutput = new byte[512 / 8];
                sha.DoFinal(shaOutput, 0);

                NBitcoin.DataEncoders.HexEncoder he = new NBitcoin.DataEncoders.HexEncoder();
                string rsaPasswordHashHex           = he.EncodeData(shaOutput);

                // create the multisig address
                PubKey[] groupMemberKeys = request.SignaturePubKeys.Select(pubKeyHex => new PubKey(pubKeyHex)).ToArray();

                var scriptPubKey = PayToMultiSigTemplate
                                   .Instance
                                   .GenerateScriptPubKey(request.RequeiredSignatureCount, groupMemberKeys);

                PublicReviewerAddressModel model = new PublicReviewerAddressModel
                {
                    PublicApiUrl = request.PublicApiUrl
                };

                // check if the API is reachable and the address can be added to the watch list
                Uri apiRequestUri = new Uri(new Uri(model.PublicApiUrl), $"/api/WatchOnlyWallet/watch?address={scriptPubKey.Hash.GetAddress(this.network).ToString()}");
                try
                {
                    HttpWebRequest apiRequest = (HttpWebRequest)WebRequest.Create(apiRequestUri);

                    ASCIIEncoding encoding = new ASCIIEncoding();
                    string        postData = "";
                    byte[]        data     = encoding.GetBytes(postData);

                    apiRequest.Method        = "POST";
                    apiRequest.ContentType   = "application/x-www-form-urlencoded";
                    apiRequest.ContentLength = data.Length;

                    using (Stream stream = apiRequest.GetRequestStream())
                    {
                        stream.Write(data, 0, data.Length);
                    }

                    HttpWebResponse apiResponse = (HttpWebResponse)apiRequest.GetResponse();

                    string responseString = new StreamReader(apiResponse.GetResponseStream()).ReadToEnd();

                    if (apiResponse.StatusCode != HttpStatusCode.OK)
                    {
                        throw new Exception($"The API request '{apiRequestUri.ToString()}' returned the status code '{apiResponse.StatusCode}'.");
                    }
                }
                catch (Exception e)
                {
                    throw new Exception($"The API request '{apiRequestUri.ToString()}' returned an error '{e.Message}'.");
                }


                // generate the RSA keypair for the address
                AsymmetricCipherKeyPair rsaKeyPair = GetRSAKeyPairFromSeed(request.RsaPassword + scriptPubKey.Hash.GetAddress(this.network).ToString());

                RsaKeyParameters rsaPublicKey = rsaKeyPair.Public as RsaKeyParameters;
                RsaPublicKey     pbk          = new RsaPublicKey()
                {
                    Exponent = rsaPublicKey.Exponent.ToByteArrayUnsigned(),
                    Modulus  = rsaPublicKey.Modulus.ToByteArrayUnsigned()
                };

                RsaPrivateCrtKeyParameters rsaPrivateKey = rsaKeyPair.Private as RsaPrivateCrtKeyParameters;
                RsaPrivateKey prk = new RsaPrivateKey()
                {
                    DP             = rsaPrivateKey.DP.ToByteArrayUnsigned(),
                    DQ             = rsaPrivateKey.DQ.ToByteArrayUnsigned(),
                    Exponent       = rsaPrivateKey.Exponent.ToByteArrayUnsigned(),
                    Modulus        = rsaPrivateKey.Modulus.ToByteArrayUnsigned(),
                    P              = rsaPrivateKey.P.ToByteArrayUnsigned(),
                    PublicExponent = rsaPrivateKey.PublicExponent.ToByteArrayUnsigned(),
                    Q              = rsaPrivateKey.Q.ToByteArrayUnsigned(),
                    QInv           = rsaPrivateKey.QInv.ToByteArrayUnsigned()
                };

                // return all the information we have
                model = new PublicReviewerAddressModel
                {
                    Network            = this.network.ToString(),
                    Address            = scriptPubKey.Hash.GetAddress(this.network).ToString(),
                    PublicName         = request.PublicName,
                    GroupName          = request.GroupName,
                    ValidFrom          = request.ValidFrom.ToString("o"),
                    ValidUntil         = request.ValidUntil.ToString("o"),
                    ScriptPubKeyHex    = scriptPubKey.ToHex(),
                    RsaPublicKeyHex    = pbk.ToHex(),
                    RsaPrivateKeyHex   = prk.ToHex(),
                    RsaPasswordHashHex = rsaPasswordHashHex,
                    PublicApiUrl       = request.PublicApiUrl
                };

                ((WalletManager)this.walletManager).AddReviewerAddressToReviewerStore(model);

                return(this.Json(model));
            }
            catch (Exception e)
            {
                this.logger.LogError("Exception occurred: {0}", e.ToString());
                return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, e.Message, e.ToString()));
            }
        }