Why is Proof of Work necessary in Blockchain? - cryptography

My question is quite simple, why can't every node in the network follow the same principle for verifying transactions:
Check that the transaction has a unique ID
Check that the digital signature is correct using the public-key of the person sending money
No one can fake sending money on the behalf of someone else because
they do not have that person's private-key and hence cannot create a
valid digital signature for that transaction. No one can copy a
previous transaction with a valid digital signature and broadcast to
other nodes again because the ID must be unique.
This would also remove the notion of "blocks" in a "chain" and lead
to a simple ledger.
I am aware that blockchains already implement this simple system of digital signatures. What I don't understand is, what is the necessity of further verification through proof-of-work? How could someone possibly create an illegitimate block (with one or more illegitimate transactions) which would require this further layer of security? What am I missing here?

You are missing double spending problem. If you have some amount of currency you can create unlimited amount of valid transactions. How you would know which one is correct?
This is why Proof-of-Work was implemented. It allows nodes to check which transactions are valid, and which try to double spend.

Related

lightning network, identity cahnnel

I want to make a service that allows to bind private user's channels to a user's account.
The user opens a private channel with my node. But I don't know which user exactly.
To identify the channel, I plan to ask the BOLT11 request from user, with a unique identifier in the description, like an SMS code.
BOLT11 specifies the target address of the payment. I will find a route for this request and thus determine the user's channel.
Is such a scheme safe? Can a fraudster create a BOLT11 request for a channel that does not belong to him? Сan you suggest a better identification scheme?
Can a fraudster create a BOLT11 request for a channel that does not belong to him?
Bolt 11 states:
The recovery ID allows public-key recovery, so the identity of the payee node can be implied
I'm not sure how every implementation matches the specification here. I would assume that all of them perform signature verification, but they might not expose public-key recovery functionality. Your idea of finding a path without actually paying the invoice might work.
However it seems that what you need is actually to identify an existing private channel between your node and the user's. Private channels should be included as routing hints in the invoice, so it might even be easier to get it from there by just decoding the invoice.
An alternative option would be to ask the user to pay an invoice generated by your node, a msat would be enough. For sure she won't be able to craft a payment with a node she doesn't control.
The safest way would be if the user signes a message with one of the keys that he uses to sign commitment transactions. This would certainly bind his identity to the channel. However current implementations don't offer that api. But that does not mean that this would not be possible

Do I need SSL for Electronic Signature Form?

I'm planning on using an online contract form where customers will agree to certain terms and conditions and sign with an electronic signature (using the mouse to spell their name). I'm wondering if this type of signature should be encrypted or if this information doesn't really need the extra layer of protection. Ideally I think having the extra layer of protection would be a good choice, but I'm a little strapped on cash.
You can get certificate for free from Let’s Encrypt. Its better than nothing.

Creating "wallets" for users with BlockCypher

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.

Best practise when storing contact information in SQL, should I encrypt?

I'm just wondering if I should encrypt user contact information when I store it in the database?
E.g. emails, phone numbers etc...
Normally you only encrypt sensitive information, and this depends on your project requirements. If the user email or phone number is sensitive, encrypt it. On the other hand, as you will need to get the contact information from database, you will use symetric encryption, and it is easy to desencrypt, so your "security" in this case is only ofuscating data and is not strong enough.
Anyway, you should always encrypt the sensitive data such as password, and I suggest assymetric encryption with hash.
In my projects I never needed to encrypt any contact information, and only passwords are encrypted on the database. If you are implementing web application, I suggest you to use security tokens (claim based security) and make all contact information to be encrypted while travel on the net (by using message or transport security) so there are very low risk to disclose any contact information to the third party.
I'm going to address the broader question: Should I encrypt?
In my VERY humble opinion, if the information is in any way associated with a person's identity and there is public access to your site or network, the answer is a resounding YES. I'll ignore the technical complexities of indexing and searching encrypted information and just give you the following to think about:
Identity and credit-card thieves and are not likely to get all your information from one source.
Information they are likely to pursue in pieces are broad. Name,
address, phone, CC number and expiration date, etc...
Once a person possesses fragmented records, all that information can
be used in an attempt to associated one fragmented record with
another. IE, John Smith in Garland, TX is likely to be J Smith at
1111 Some Dr, Garland, TX.
Once successfully associated, fragmented records from YOUR data
combined with fragmented records from MY data become a complete
record, then OUR customer's life is a wreck.
This is a very simplified path, and lots of information is public record so in one sense protecting it is a moot point. However, if you are slapped with a lawsuit, and it DOES happen, that may be of little comfort when you're coughing up $500 a hour to your attorney.
Encrypting contact information only makes sense if you expect your security to be compromised or know that untrustworthy people will have direct access to your database.
One-way encryption (hashing) will render your data useless since there is no way to retrieve it so you'll have to use some form of reversible encryption.
Encrypting contact info in your database will have a couple of downsides, most notably:
Encryption is not free, it takes time to process the data
You cannot search the encrypted data based on partial data like a partial contact name
Note that the weakness of reversible encryption lies with the key required for decryption. Don't store that in the same database.
Using transport layer security (like SSL) makes more sense.

When working with most APIs, why do they require two types of authentication, namely a key and a secret?

I have been working with APIs and I've always wondered why you have to use a key and a secret?
Why do you need two types of authentication?
When a server receives an API call, it needs to know two things: Who is making the call, and whether or not the call is legitimate.
If you just had one item ("key"), and included it with every call, it would answer both questions. Based on the "key" the server knows who you are, and because only you know the key it proves that the call is actually coming from you. But including the key with every call is bad security practice: if someone can read even one of your messages in transit, your key is compromised, and someone can pretend to be you. So unless you're using HTTPS, this approach doesn't work.
Instead, you can include a digital signature with every call, signed with some "secret" number. (The "secret" number itself is not sent). If an attacker manages to read your message, they won't be able to figure out this "secret" number from the signature. (This is how digital signatures work: they are one-way).
But this doesn't solve the identification question: In the latter case, how does the server know who is making the call? It could try to verify the signature against the "secret" of every single user, but of course this would be very time-consuming.
So, here's what we do: Send both a "key" (that identifies the user), and a signature created using the "secret" number (that proves that the message is legitimate). The server looks up the user based on the key, and then validates the signature using that user's "secret" number.
This is a bit like when you write a check: It has an account number on it (to identify you) and your signature (to prove that you're you). Having just the account number wouldn't prove that you actually wrote the check. Having just the signature without the account number would force the bank to compare your check against all of its signatures for all of its accounts, which would obviously be inefficient.