Pages:
Author

Topic: Payment Address Validation (Read 1757 times)

full member
Activity: 182
Merit: 107
March 06, 2017, 08:07:03 PM
#21
Remember the incident where some people were running bitcoind on linode and a linode employee stole private keys?

Yeah, that can happen with your web server private keys too. That's why the ability to have the signing key for address validation on an offline computer is so important.

Anyway I think I'm done, I've put my idea out there. Make of it what you want, I don't write BIPs because there is too much politics involved, so if someone who does write BIPs and sees the value in this, have at it.
full member
Activity: 182
Merit: 107
March 06, 2017, 07:07:52 PM
#20
From the BIP it looks like it is not even possible to secure payment requests with DANE.

DANE secures PKI by requiring a fingerprint of the key in DNS secured by DNSSEC, but that fingerprint is in a TLSA record which requires a specific port and protocol. A fingerprint valid for TCP on Port 443 may not be valid for TCP on Port 25 even though the domain name is the same.

It doesn't look like payment requests even allow for that kind of fidelity when PKI is used.

e.g. the same key that is used on the web server would validate, the same key that is often on webservers in a hosting center where a lot of people who work for the hosting company potentially have access to the private key.

With the solution I am proposing, the public key is in DNS and the key used to sign the payment addresses does not even have to be online (though it would have to be online if you let the web server generate deterministic addresses)
full member
Activity: 182
Merit: 107
March 06, 2017, 06:31:20 PM
#19
Can someone explain to me what mechanism payment requests have to prevent a fished MITM payment request, e.g. to example.photos instead of example.photo ?? (yes both TLDs exist).

EDIT -

Also according to the BIP - https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki - cryptographic signatures are optional, and when used, are validated by the PKI system which we know is not secure (easy to get fake certificates) rather than by DNSSEC which is a lot harder for malicious signatures due to the superior design of DNSSEC (no certificate authorities to trust).

PKI also has the problem that not all systems trust the same certificate authorities. DNSSEC does not have that problem.
full member
Activity: 182
Merit: 107
March 06, 2017, 05:04:15 PM
#18
bip39 supports passphrases so you can have more than one secret behind your HD wallet.

Spare me your opinion. It's fine that you don't like my idea, but I don't think you really understand what I am doing or talking about.

I admit that I'm not sure what you are up to because you've done a piss poor job of explaining it. Maybe you control the bitcoin clients your users use in which case you can do what you like.

Quote
Having the ability for the client to verify a payment address with cryptography is not a bad thing, and if implemented you don't have to use that feature if you do not want to.

Once again that's what payment requests do.

Anyway I'm out.


Not all clients support payment requests, Bitcoin is a protocol for creating and validating transactions. Clients support the protocol for creating and validating those transactions. What else they do, be it deterministic address generation or payment requests is up to the client.

With respect to deterministic addresses, why I don't like them is as I stated there must be a mathematical relationship in order for public key A to generate B and C that private key A can then determine the private key for.

How to exploit that mathematical property may not yet be known, if a method even exists, but remember that the logjam attack on DHE ciphers was well known to the NSA long before it was known to the public, hence why ECDHE is what people really should be using for forward secrecy - or DHE with at least 2048-bit groups preferably generated locally rather than from the RFC.

I have not seen a mathematical proof that says it is impossible to show that public keys B and C have a greater than X probability of being generated from the same unknown deterministic key A. Until I see a mathematical proof that such a technique would be impossible to develop (and X doesn't have to be 100%, even 5% would be dangerous) I do not trust that deterministic key technology is not a possible privacy leak.

For a wallet it is probably fine, though it may make it easier to determine which output in a transaction is a change address, but wallet technology itself is rather poor with respect to privacy. Hopefully clients with better handling of how they spend emerge but they do not really exist now, one has to use multiple wallets to keep their BTC spending from being associated together.

For a business that receives transactions, though, privacy of customers is extremely important. It can't be as easy as the .gov making a small payment and then finding payments addresses related to the one they made in order to find out what wallets made payments to that company.

-=-

Payment requests may be a solution but it isn't the only solution to the problem of knowing that you are paying the right address. And they are not universally supported or required for a bitcoin client to implement, just like my DNS based public key and address signatures would not be required for a client to implement.

With multiple solutions, the free market can decide which is the solution they want to use.

Just like we are free to use libbitcoin instead of bitcoind or are free to use armory instead of bitcoin-core.
legendary
Activity: 3682
Merit: 1580
March 06, 2017, 09:58:57 AM
#17
bip39 supports passphrases so you can have more than one secret behind your HD wallet.

Spare me your opinion. It's fine that you don't like my idea, but I don't think you really understand what I am doing or talking about.

I admit that I'm not sure what you are up to because you've done a piss poor job of explaining it. Maybe you control the bitcoin clients your users use in which case you can do what you like.

Quote
Having the ability for the client to verify a payment address with cryptography is not a bad thing, and if implemented you don't have to use that feature if you do not want to.

Once again that's what payment requests do.

Anyway I'm out.
full member
Activity: 182
Merit: 107
March 06, 2017, 01:50:05 AM
#16
btw - another benefit of not using deterministic keys -

The seed that is used for my generation method can be backed up at one location and the script at another.

If the backup seed is ever compromised, it can not be used to steal value that exists in payments addresses unless the perpetrator is also able to compromise the backed up script that takes the seed and generates the addresses and the salt that the script uses (the salt is essentially a second seed).

The seeds don't even need to be valid keys.

That kind of paranoia may not seem reasonable to you, but it does to me.
full member
Activity: 182
Merit: 107
March 06, 2017, 01:38:28 AM
#15
Maybe I am being paranoid - but when you use a deterministic address where the address is generated from a public key such that the corresponding private key can know there was a payment, I suspect there is a mathematical way to determine payment addresses are related.

No there isn't. The only way to tell they are related is because they show up in transactions together when you go to spend your coins. This applies to all wallet types including the old fashioned non-deterministic ones.

They are mathematically related, they have to be in order for the private key associated with the public key seed to find the value.

Do you have a mathematic proof demonstrating the relationship can never be inferred from the signatures use to spend the value? I would like to see it.

Quote
Of course if you are worried about people finding out that the addresses are related by looking at the blockchain you can simply use coin control features as found in electrum or bitcoin core to pick your inputs manually and avoid revealing any links between your addresses.

Also in case you didn't know even Bitcoin Core is now deterministic.

For a wallet that is fine. However I don't use bitcoin-core to generate payment addresses for e-commerce. I use a python script that I wrote. It isn't deterministic. It does use a seed but it does not use the deterministic properties of ECC.

Quote
BTW regarding generating lots of private keys offline please do read this:

https://bitcointalksearch.org/topic/fastest-least-likely-to-be-subtly-broken-way-to-make-lots-of-addresses-offline-912337

Pay special attention to posts by gmaxwell and dabura667 (especially post #8)

What point are you trying to make?

I don't use bitcoind to generate keys.

Quote
Quote
Also if the client is coming up with a deterministic address, how the fuck do I know what invoice it is for?

I just made all that up. No client supports picking up xpubs from DNS, validating DNSSEC and then generating an address to send payments to. Stealth addresses are the closest thing to that but they are not widely supported.

Payment requests OTOH are very well supported. Just use that and spare us Smiley

Spare me your opinion. It's fine that you don't like my idea, but I don't think you really understand what I am doing or talking about.

Having the ability for the client to verify a payment address with cryptography is not a bad thing, and if implemented you don't have to use that feature if you do not want to.
legendary
Activity: 3682
Merit: 1580
March 05, 2017, 03:33:05 PM
#14
Maybe I am being paranoid - but when you use a deterministic address where the address is generated from a public key such that the corresponding private key can know there was a payment, I suspect there is a mathematical way to determine payment addresses are related.

No there isn't. The only way to tell they are related is because they show up in transactions together when you go to spend your coins. This applies to all wallet types including the old fashioned non-deterministic ones.

Of course if you are worried about people finding out that the addresses are related by looking at the blockchain you can simply use coin control features as found in electrum or bitcoin core to pick your inputs manually and avoid revealing any links between your addresses.

Also in case you didn't know even Bitcoin Core is now deterministic.

BTW regarding generating lots of private keys offline please do read this:

https://bitcointalksearch.org/topic/fastest-least-likely-to-be-subtly-broken-way-to-make-lots-of-addresses-offline-912337

Pay special attention to posts by gmaxwell and dabura667 (especially post #8)

Quote
Also if the client is coming up with a deterministic address, how the fuck do I know what invoice it is for?

I just made all that up. No client supports picking up xpubs from DNS, validating DNSSEC and then generating an address to send payments to. Stealth addresses are the closest thing to that but they are not widely supported.

Payment requests OTOH are very well supported. Just use that and spare us Smiley
full member
Activity: 182
Merit: 107
March 05, 2017, 08:24:01 AM
#13
Maybe I am being paranoid - but when you use a deterministic address where the address is generated from a public key such that the corresponding private key can know there was a payment, I suspect there is a mathematical way to determine payment addresses are related.

That is why I do not use deterministic addresses, I don't want someone to be able to go through the blockchain and determine what payment addresses of mine are related (come from the same seed). I use a private mechanism for generating payment addresses where I first generate private keys involving a salt etc. and then the payment address from those generated private keys.

I do it this say so that someone without knowledge of the seed can not determine if two payment addresses are likely related.

Thus providing a signature for the address that the client can use to validate the address is in my opinion of value.

There are many people who do not use deterministic addresses, they are mathematically cool but I fear that same math allows them to be mined for relationships and is a potential privacy issue.

A libsodium generated signature and corresponding key is easy and works.

Why is what you are suggesting superior?

-=-

Also if the client is coming up with a deterministic address, how the fuck do I know what invoice it is for?
legendary
Activity: 3682
Merit: 1580
March 05, 2017, 05:37:47 AM
#12
  • Replace the web page file on the webserver with one that has the attacker's master public key

Why not just replace the web page?

Payment requests work because we rely on commercial CAs to validate identities. How is the server's public key going to be checked in this scenario?



What I'm suggesting has nothing to do with certificate authorities.

The public key would be in DNS - and secured by DNSSEC.

I would suggest using libsodium for signing the payment address, because libsodium is a lot easier to implement and also has support in PHP via a PECL module and will have native support in PHP in PHP 7.2.

So sign the address with libsodium, and put the public key in DNS secured by DNSSEC.

If users' bitcoin clients are going to check dns then why publish the address on the web page at all? Let the bitcoin wallets grab the xpub from dns and send to some address derived from that.
full member
Activity: 182
Merit: 107
March 05, 2017, 01:57:15 AM
#11
  • Replace the web page file on the webserver with one that has the attacker's master public key

Why not just replace the web page?

Payment requests work because we rely on commercial CAs to validate identities. How is the server's public key going to be checked in this scenario?



What I'm suggesting has nothing to do with certificate authorities.

The public key would be in DNS - and secured by DNSSEC.

I would suggest using libsodium for signing the payment address, because libsodium is a lot easier to implement and also has support in PHP via a PECL module and will have native support in PHP in PHP 7.2.

So sign the address with libsodium, and put the public key in DNS secured by DNSSEC.
legendary
Activity: 3682
Merit: 1580
February 25, 2017, 03:10:49 AM
#10
  • Replace the web page file on the webserver with one that has the attacker's master public key

Why not just replace the web page?

Payment requests work because we rely on commercial CAs to validate identities. How is the server's public key going to be checked in this scenario?

full member
Activity: 182
Merit: 107
February 22, 2017, 10:08:55 AM
#9
- snip -
However, I still don't see how this solves your problem. If someone injects an address into your database, then you probably won't know that that happened and still end up signing the address and giving it out anyways.

I think (hope) the idea is to pre-sign all the pre-generated addresses at the time they are generated and store both the address AND the signature in the database.

Yes, just like with DNSSEC where the zone files are signed offline and uploaded to the nameserver so that even if the nameserver itself is hacked, fake responses won't validate because the private key isn't there.
Bind is starting to screw that up now by having on the fly DNSSEC signing capabilities with signing key on nameserver but smart admins don't do that.

The signing key would not be on the SQL server or any of the web application servers.

Quote
I also assume that the plan is to have the master public key statically embedded directly in a webpage file on the web server, so that the attacker can't inject his own master public key into the database.

Exactly.

Quote
In this way, the attacker would need to be able to accomplish ALL of the following for a successful attack:
  • Inject an address into the address database table
  • Inject a signature into the signature database table
  • Replace the web page file on the webserver with one that has the attacker's master public key

Exactly.
legendary
Activity: 3472
Merit: 4801
February 22, 2017, 09:36:56 AM
#8
- snip -
However, I still don't see how this solves your problem. If someone injects an address into your database, then you probably won't know that that happened and still end up signing the address and giving it out anyways.

I think (hope) the idea is to pre-sign all the pre-generated addresses at the time they are generated and store both the address AND the signature in the database.

Since the attacker doesn't have access to the private key, he won't be able to generate a valid signature to replace in the database when he injects his fake address.

I also assume that the plan is to have the master public key statically embedded directly in a webpage file on the web server, so that the attacker can't inject his own master public key into the database.

In this way, the attacker would need to be able to accomplish ALL of the following for a successful attack:
  • Inject an address into the address database table
  • Inject a signature into the signature database table
  • Replace the web page file on the webserver with one that has the attacker's master public key
staff
Activity: 3458
Merit: 6793
Just writing some code
February 22, 2017, 09:06:30 AM
#7
BIP 70 has something similar to what you are trying to do. It has the option to allow merchants to sign the payment request with a X.509 certificate to prove that the request and thus the address to pay is actually theirs.

However, I still don't see how this solves your problem. If someone injects an address into your database, then you probably won't know that that happened and still end up signing the address and giving it out anyways.
full member
Activity: 182
Merit: 107
February 22, 2017, 08:35:00 AM
#6
For what it's worth, I don't create new addresses with the normal deterministic method people use.

I use my own method that works extremely well, and it is not possible to determine if two addresses are related. That's why I won't generate addresses on the web server.

I'm sure many would say I'm doing it wrong because I'm doing it differently, but I have me reasons. Anyway - it is not related to what I am suggesting here, which is a method for clients to leverage DNSSEC to fetch a public key (which doesn't have to be related to the keys or even the same ECDSA curve bitcoin uses) to verify the authenticity of the address a payment is being made to.
full member
Activity: 182
Merit: 107
February 22, 2017, 08:12:23 AM
#5

There are many problems with this. First of all you are supposed to trust your own servers. You can't design an app where you think some of the servers might be compromised while the others aren't. That's just crazy.

NO NO NO NO FUCKING NO.

Trust by itself is the cause of so many software compromises.

Never trust when verification is an option.

When verification is not an option, find a way to make it an option.

Quote
Second if you are going to store the public ecdsa key then you might as well use that to generate addresses independently on the webserver.

That's one way, but it has nothing to do with what I am suggesting here - which is a way for bitcoin clients to validate a payment address belongs to the web server they are buying something from.
legendary
Activity: 3682
Merit: 1580
February 22, 2017, 04:34:53 AM
#4
addresses are not private. the private portion is called the private key. in  order to generate addresses without exposing the private key you simply install the wallet's extended public key aka xpub and master public key on the server. then you can safely generate all the addresses you like without risking theft of bitcoins sent to said addresses because it isn't possible to generate the private keys from the xpub.

opensource code to do the above is available for a variety of languages. if you tell me which language your app is coded in maybe i can point you in the right direction. for example for php there is bitwasp's libraries:

https://github.com/Bit-Wasp/bitcoin-php

and smaller set of libraries in the bitcoin way plugin:

https://wordpress.org/plugins/bitcoin-payments-for-woocommerce/

note that you need a bip32 deterministic wallet for this. you shouldn't be using any other type of wallet anyway. software that creates deterministic wallets includes electrum, mycelium, bitcoin core and bitpay wallet.

Ofcourse addresses are not private.

I don't want the servers do any address generation, deterministic or not. They just fetch an address when someone wants to send money.

But I do insist upon the web server having a way to validate the address it fetched belongs to me, not to a hacker who injected it into the database (which is likely a different server than the web app front-end) and that's why I create a signature for each address signed by the private ECDSA key I use as a seed on my machine that generates addresses. The signature in hex is only 128 characters long, and the public (not private) ECDSA key from the seed can then be used to validate the signature was generated by someone with the private key.

There are many problems with this. First of all you are supposed to trust your own servers. You can't design an app where you think some of the servers might be compromised while the others aren't. That's just crazy.

Second if you are going to store the public ecdsa key then you might as well use that to generate addresses independently on the webserver. This is deterministic address generation. Why bother with the whole signature generation and validation?

Quote
It would defend against MITM attacks (which can happen even with TLS) changing the payment address, and it would defend against malicious attackers injecting their own payment addresses into the web application.

bitcoin payments can't be reversed, so we have to defend against that kind of fraud before it happens. Validating the payment address really belongs to the website using cryprography is the only sure way to know it does.

Payment requests are similar to what you are talking about here. That uses TLS which for some reason you don't like. I don't know what to say.
full member
Activity: 182
Merit: 107
February 22, 2017, 02:28:13 AM
#3
addresses are not private. the private portion is called the private key. in  order to generate addresses without exposing the private key you simply install the wallet's extended public key aka xpub and master public key on the server. then you can safely generate all the addresses you like without risking theft of bitcoins sent to said addresses because it isn't possible to generate the private keys from the xpub.

opensource code to do the above is available for a variety of languages. if you tell me which language your app is coded in maybe i can point you in the right direction. for example for php there is bitwasp's libraries:

https://github.com/Bit-Wasp/bitcoin-php

and smaller set of libraries in the bitcoin way plugin:

https://wordpress.org/plugins/bitcoin-payments-for-woocommerce/

note that you need a bip32 deterministic wallet for this. you shouldn't be using any other type of wallet anyway. software that creates deterministic wallets includes electrum, mycelium, bitcoin core and bitpay wallet.

Ofcourse addresses are not private.

I don't want the servers do any address generation, deterministic or not. They just fetch an address when someone wants to send money.

But I do insist upon the web server having a way to validate the address it fetched belongs to me, not to a hacker who injected it into the database (which is likely a different server than the web app front-end) and that's why I create a signature for each address signed by the private ECDSA key I use as a seed on my machine that generates addresses. The signature in hex is only 128 characters long, and the public (not private) ECDSA key from the seed can then be used to validate the signature was generated by someone with the private key.



the string on the right is the signature of the address to its left, created using the private seed used for address generation and the address.

The public key that corresponds with the seed can then be used to validate them.

What I am suggesting is that, say, for example www.example.com is selling snake oil for bitcoin.

They can put a public key in DNS protected by DNSSEC and then sign all their bitcoin payment addresses uses the corresponding private key.

When I want to buy some extra fine snake oil, the bitcoin URI on their website includes the signature.

My client fetches the public key from DNS and if it DNSSEC validates, then uses it to check the signature matches the address with the public key.

That's what I want to see bitcoin clients able to do.

It would defend against MITM attacks (which can happen even with TLS) changing the payment address, and it would defend against malicious attackers injecting their own payment addresses into the web application.

bitcoin payments can't be reversed, so we have to defend against that kind of fraud before it happens. Validating the payment address really belongs to the website using cryprography is the only sure way to know it does.
legendary
Activity: 3682
Merit: 1580
February 22, 2017, 01:58:54 AM
#2
addresses are not private. the private portion is called the private key. in  order to generate addresses without exposing the private key you simply install the wallet's extended public key aka xpub and master public key on the server. then you can safely generate all the addresses you like without risking theft of bitcoins sent to said addresses because it isn't possible to generate the private keys from the xpub.

opensource code to do the above is available for a variety of languages. if you tell me which language your app is coded in maybe i can point you in the right direction. for example for php there is bitwasp's libraries:

https://github.com/Bit-Wasp/bitcoin-php

and smaller set of libraries in the bitcoin way plugin:

https://wordpress.org/plugins/bitcoin-payments-for-woocommerce/

note that you need a bip32 deterministic wallet for this. you shouldn't be using any other type of wallet anyway. software that creates deterministic wallets includes electrum, mycelium, bitcoin core and bitpay wallet.
Pages:
Jump to: