I'm new to the world of Bitcoin, and I am having a hard time trying to understand the basics of wallet implementation for a basic bitcoin service.
Basically, I'd like that:
Users have a personal wallet ("in-site" wallet, keeping track of their balance)
Users are able to deposit/withdraw into/from that address/wallet
The web service is able to make transactions on behalf of the user
(to other addresses)
I know there are plenty of ways to go about this, and there are many APIs that can help, so I will narrow this problem down to using BlockCypher's API, which I believe has many similarities with other APIs.
I'd just like to know the general steps one should take to implement this, since I'm pretty much lost. How do I start?
I was thinking that the steps I should take are:
With the API, generate an address (server side?) and store the private and public keys in a database. Use the same address for the same user all the time.
Use the transactions API to do the rest and keep track of Bitcoin balance.
However, this put me off a bit (coming from BlockCypher's API, on address generation):
The private key returned is immediately discarded by our servers, but
we advise that these keys should not be used for any high-value—or
long-term storage—addresses.
The wallets I intend to use would be considered "long-term" storage, I guess, so what other way I could go about implementing such a system?
I'm sorry if this is a very basic question, or if I'm misunderstanding. It'd be great to have some guidance on the right direction; of course I don't expect full-code examples, just an explanation of the concepts. Thanks.
The Bitcoin private key is essential to using the wallet. Bitcoin is based on the PGP idea - one private key corresponds to one public key.
The API that you are using immediately discards the private key, otherwise they would be able to spend the money in every wallet they generate. They would do this by creating transactions and signing them with the private keys that they had.
So they generate these private keys in memory, send them to you via the API, and then discard them. BlockCypher's discarding the private keys does not impact your receipt of these keys. You still get the keys via the API and will have them in memory on your server.
You need to store these private keys in persistent storage, such as a database. Once you do that, then you can transact on behalf of users.
In regards to the long-term storage aspect, they are referring to the strength of the private key used to generate the wallet. Given this, they are likely not extremely strong (it does not mean they are weak!). You want a strong private key so it is not easily hacked or guessed. For long-term storage, especially of high dollar amounts, those wallets are available on the blockchain and are a hacking target. For long-term storage, you're better off with a Trezor or reading up on encryption (which is best done at security.stackexchange.com.
Related
Using HTTPS, we could actually get the certificate and the public key of google.
In the case that we do not care about privacy. How about letting the smart contract to check the signature of the data sent by a website.
A simpler solution: Maybe hard code the public key of the data source into the smart contract?
Your idea is reasonable, and has been invented in 2015 by Emercoin team.
emerSSL already stores in the blockchain hash of user's SSL-certificate. And this system already works in production, for example, on Livecoin exhcange.
I have seen that in the released projects (like Supply Chain) an off-chain database is used to save the user's information and state data. Is it possible to avoid using this database to save user information or is an implicit pattern of Sawtooth applications?
Private keys must be stored securely. At a minimum that means making the private key file unreadable to everyone but the owner (uw+o or 0600 permission). It is also a good idea to restrict access to the machine storing the private keys, if possible.
Better yet, use a software or hardware keystore (such as a hardware HSM).
Sawtooth does not store private keys in the global state or any database.
Public keys, which are not used for signing (just verification) are present in transactions and the blockchain.
It seems to me that if my private and public key are compromised (which i use to sign and verify JWTs), that anyone can independently generate JWT tokens for themselves to use on my API?
Whereas on the other hand if I generated my own tokens myself, and stored a look-up table of 'one-way-hashed user id' => 'token', then if someone broke into my system, they would not be able to generate tokens to use on my API, and they would also not be able to use the tokens (because they would not know which token belonged to which user)
If someone breaks into your system and it is still secure, then you made a secure system; nothing to worry about.
with JWT, it appears to me that if someone breaks in, I do have something to worry about.
It seems to me that if my private and public key are compromised (which i use to sign and verify JWTs), that anyone can independently generate JWT tokens for themselves to use on my API?
Yes, that's correct.
Public keys are intended to be public and can be distributed.
On the other hand, private keys are supposed to be private and must be kept secure in your server. Anyone who has access to the private keys should be capable to issue tokens.
Disclosing your private key is a huge security breach.
It seems to me that if my private and public key are compromised (which i use to sign and verify JWTs), that anyone can independently generate JWT tokens for themselves to use on my API?
As also pointed out that you need to keep your Private Key Secure , the best way to keep it secure is to use an HSM for signing your data , in this case you can extend the JWT generator to sign the data through a crypto dll inside the HSM , this insures that the private key is never exposed outside the HSM
Whereas on the other hand if I generated my own tokens myself, and
stored a look-up table of 'one-way-hashed user id' => 'token',
Any one can generate your non-keyed hash. Secure hashes involved a private key which becomes a digital signature. Now we've come full circle, because that's exactly what a JWT token is.
Alternatively, you store them in a datastore, but now you must query this on every round trip. Most ticket(cookie)/token authentication systems use public key verification, which verifies the validity of the ticket/token without a database roundtrip.
If you store them in a datastore, now you must track expiration in the datastore as well. Tickets/tokens can have an expiration built into them. The nice thing about tickets/tokens is the client holds them. You can expire a session more quickly than the authentication. I.e. often you get a ticket that may allow you to be logged in for 2 hours, but the web server can expire your session in 10 minutes to reduce memory usage. When you access the web server in 15 minutes, it will see your ticket/token and see that it is still valid, and create a new session. This means at any point in time the server is tracking far fewer idle users.
JWT issuers are great for distributed systems, where authentication is shared. Rather than reimplement the authentication in every system, exposing multiple systems to the private key, as well as potential bugs in the authentication, we centralize it to one system. We can also leverage third party integrators that generate JWTs. All we need to do is get their public key for verifying the JWTs.
If someone breaks into your system and it is still secure, then you
made a secure system; nothing to worry about.
I have your list of nonces you were saving in your database now, and can login as anyone. I also likely have your connection strings, even if you're encrypting your application config, if I have root access then I can access the same key store that's used by the application to decrypt them. Now I get your username/passwords from your database and can login as anyone, regardless of what authentication scheme you use.
You'll be hard pressed to find a system that can still be secure after someone's gained root or physical access to the machine.
There's a small handful of systems that have purpose built hardware for storing keys and handle requests for encryption operations through an interface, thus ensuring the keys are protected at a hardware level and never accessed directly from software:
https://en.wikipedia.org/wiki/Hardware_security_module
I am working on a project where two parties can each make API requests to each other and are authenticating using a shared secret. The other party wants the shared secret to be the same both ways, but I don't understand how that would work. So I'm either looking for an explanation of how to do this securely, or to find out if this is not something that is possible and that the shared secrets should be different based on the direction of the request.
If the API request were just going in one direction, I would salt the password using a key defined function, and store the hash and salt, then I can authenticate the user by generating and matching the hash on each request. But if I need to use that same shared secret to make requests to the other API, then it seems like I would need to store the password in a way that it can be decrypted, which seems wrong/not possible.
Is there a way of doing this, or should the shared secret be different depending on which direction the request is going?
Your analysis is correct. If both side can be the caller, then both sides need to know the secret (not just be able to verify it).
Having two separate keys (one for each caller, you might as well call them "passwords" in this use case) seems to be a reasonable default setup.
It is always good to think of "parties" and give each their own credentials, especially if more parties will be involved later. Makes it much easier to revoke individual access rights later on, to enforce fine-grained access control, and minimizes the impact of leaked credentials (an attacker can only impersonate that one party, not anyone else in the system).
Having just one may appear slightly easier to manage, but then you become responsible for not leaking the other guy's key (in addition to your own). I would try to avoid that extra burden.
The RSA algorithm is used for encryption (plain text to cipher text) and decryption (cipher text to plain text) of data. What is the need for using public keys in these sites; why is data encrypted as everything is viewed by everyone?
Why do we need to use public key cryptography in Google; how does it provide security?
What is the need for using public keys in these sites?
It is required to set up a shared secret (a big random number) that is used for further symmetric crypto. Public-private key crypto allows one to share a secret message (symmetric key material) even when each and every message is monitored and eavesdropped. See Hot does SSL works? for more info.
The problem with public-private key crypto is that it is dead slow, whereas symmetric crypto is dead fast. The benefit is that public-private key crypto uses two keys for encryption and decryption and this is what allows to securely share a secret through the insecure channel, whereas symmetric crypto uses a shared key for both operations and you need both parties to have the same shared key.
Why is data is encrypted as everything is viewed by everyone?
When data is encrypted all that an observer can see is pure random noise. An observer cannot understand anything from the encrypted communication. Unless storing encrypted communication, like NSA does, and later asking Google and other companies for their private key. In this way they can decrypt old communication.
Why do we need to use public key cryptography in Google; how does it provide security?
Many agencies would like to know what people search for: "how to make a bomb", political disputes, etc. Advertisers would like to know what people interested in so that they can bring relevant ads. If something is provided to you for free, you are the product. You sell your information (your interests) and when this is done on a global scale suddenly huge money become involved.
Public-private key crypto in this sense provides privacy. Only you and the server can understand the traffic, but no one else: no intermediate hubs, your ISP or government body.
Before Facebook switched to SSL-by-default, all traffic was indeed plain text. This made it possible to build a graph of connections on a truly global scale. The rational I guess was to possibly aid anti-terrorist forces to catch the bad guys. From the other side all population's activities were tracked. See PRISM for more info.