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.
Related
I'm working on a distributed application, and we need a way to authorize clients. Every client has a PGP keypair associated with them, and we require them to enter their private key (which is not stored) through which their pubkey is derived and used to identify clients and modify their fields on the distributed database.
Now, considering user experience, entering a private key on a website whenever you need to do something is troublesome. But we also cannot maintain a central database for username/password based authentication as that creates a single failure point (not what the distributed application is meant to do)
I am hoping there is some way to get an easier to remember human readable descriptor of the private key which can be used to authenticate if something like that exists. Any other ideas are appreciated too.
I'll throw a bunch of ideas to clarify the question:
Are you certain that PGP is suited for your needs?
I feel like you should provide some more details to be sure:
- How are the private and public keys used exactly? I understand the following : user inputs its private key, information is decrypted and modified, public key is deduced from private and used to encrypt the updated information.
- How is this different from using a regular password and being able to authenticate the user and encrypt data?
- You seems to send private keys on the network, and they should remain private.
How you could use a regular password:
User has a password, your application uses a function (e.g sha256, KDF,...) to make it usable by classical encryption algorithms (e.g AES). With the same (not stored) key, you can then encrypt and decrypt datas. You just have to make sure that decryption is valid, by adding a known value at the beginning of the data (e.g a part of the key).
Quick example:
password: "WeakPassword"
key: sha256("WeakPassword"+"MySalt") = 493e3ae...b2eec8ef
Decrypt(data,key)
clearData = "493e3ae{123;456}" //valid, because you can check the beginning
Encrypt(clearData,key)
Advantages: usable passwords, faster symmetric encryption
Use a QR code
If you stick to PGP and have a camera available it is pretty handy.
You could also use hexadecimal, base64, ... but for a 2048 bits RSA key, that still gets you hundreds of characters.
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'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.
I would like to encrypt some of my Windows 8 app data (stored in local storage folder). This is not very sensitive data, however I would like to prevent users from forging/modifying it (and was looking into encryption as a way to achieve that).
Is there any secure key store available that I could use to save my key for later reuse? What I would like to do is:
1) on the first run generate the key and store it somewhere,
2) encrypt the data using the key,
3) anytime i need to decrypt the data i would retrieve the key from the store.
Did you have a look at the PasswordVault class yet? http://msdn.microsoft.com/en-us/library/windows/apps/windows.security.credentials.passwordvault.aspx
Basically all confidential information should go in there.
If you want to 'prevent users from forging/modifying it', the question is, how much energy you are willing to put into this.
Generally speaking, data in the PasswordVault should be secure without using additional encryption. Regarding security above that level it can be said that an attacker with physical access to the computer can do anything with it, as you'd have to store the keys on the same machine. Anything more swiftly reaches a point of diminishing returns against invested effort - i.e. just adding some obscurity instead of real security.
Be careful with the PasswordVault solution, I discovered that it is actually a problem because it is a roaming settings. If you open your application on two devices at the same time, you will get two encryptions keys, but after a day or so, the roaming setting will override the first generated encryption key.
In a Mac application, I have a requirement to store the private key sent from the server for logged in user in a secure way and retrieve it back whenever needed programmatically. I know that keychain is the best place to store the private key. Is there any sample code available to achieve this?
I am able to add the private key to the keychain using "SecKeychainItemImport" method of "Security.framework" but having issues retrieving back the private key from the keychain. I have tried using "SecKeychainItemCopyAttributesAndData" and "SecKeychainItemCopyContent" methods for getting private key back from the keychain. But no luck so far.
I have also read in blogs mentioning private key storage inside ".ssh" hidden folder. But I feel that storing the private key inside the keychain provides one more level of security so that someone else can not have an easy access to the private key.
One purpose of the Keychain is to keep private keys protected by not exposing their data to the application. To prevent accidentally exposing a private key, these items are flagged CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_SENSITIVE by default; i.e., it is only possible to get their data using SecKeychainItemExport, and only in a passphrase-protected format.
There are APIs in the Security framework that encrypt/decrypt/sign/verify etc. data using a supplied key item without ever putting the raw key data in the application's address space. (These operations are normally done by a separate, privileged process.)
If for some reason you do need access to the private key's raw bits, you need to prepare for this at the time you import the private key to the keychain. You need to set keyAttributes to CSSM_KEYATTR_EXTRACTABLE (i.e., without the sensitive bit) in the keyParams parameter of SecKeychainItemImport.
Yes, the Keychain is what you'd use here. You want to read the documentation first, then look at Apple's sample code.
http://developer.apple.com/library/mac/#documentation/Security/Conceptual/keychainServConcepts/01introduction/introduction.html
http://developer.apple.com/library/ios/#samplecode/GenericKeychain/Introduction/Intro.html