Client side authentication through signatures instead of passwords

I want to save some user-generated data with some signature of the user that generated it (let’s say that the user has to fill some forms with some data and I want him to sign the written data).

The server side is some random server language (that has big enough libraries to cover everything I’ll need to do), the client side is Javascript (and the webapp is a SPA, Single Page Application). The client machine can be a cellular (a fairly new smartphone… but still a slow CPU compared to standard desktops/laptops)

The DB backend is “insecure”. It is possible to tamper the data (many persons have access to the machine, perhaps it’s “in the cloud”), but there is and a strong sequential continuous backup where it is very difficult to tamper with the already written data (something similar to a secured sequential log) (perhaps a digest of the log is shipped continuously to a secure server, or the sequential log is kept in another cloud totally separate from the first one, or if it only has to save some hashes, even a random machine can do it).

What I want to be able to do is make very difficult for third parties that have read/write access to the DB machine and read access to the server machine to add/modify records created by the user. For the deletion I’ll do this: the program doesn’t do any real update/delete operation. Every update/delete simply add a new version of the data and marks the old as “old”. The hash of all the data is continuously saved on the tamper proof backup. This will even protect me from updates to old data. The only thing it won’t protect me is against adding new data through spoofing an existing user.

I will use https to secure transmission (with certificates bought from some SSL cert authority).

I know I can’t really secure the site (as in “the javascripts that will go to the user”), so that this is a weak point (someone could install a keylogger directly in the javascript code). I’ve watched around but it doesn’t seem possible to sign some javascript code, send it to a client and let the client check the signature (probably because the javascript, being a dynamic language, would let a malicious javascript inject himself in the signed code/in a random piece of the javascript base library, so it would be very difficult to firewall everything the pre-existing environment). I could check the signature from the server side (the server program is signed and sends only javascripts that are signed).

I don’t want to use client-side SSL certificates because they are difficult to use for the user (if the user changes computer he has to reinstall the certificate, if the user forgets he has a certificate in a computer it’s possible to steal it…)

The solution I thought was to use ECDsa, generate a public/private keypair from the user password (plus some other data) and then the client signs the user’s data client-side. The public/private key generation happens client side. When the user is created and the password is chosen, the client generates the public/private keypair and tells the server the generated public key. The user only needs to remember its password.

Clearly the weak point of this is that someone could add a new public key of the user on the server and sign something with the new public key, but it would be quite easy to spot this, because there would be a new public key. Something more clever would be to change an old public key and then resign everything the user signed with that new key, so it would be impossible to show if the data was tampered, but for this there is the tamper-proof log.

Another weak point would be from the user side: someone could install a keylogger and steal the password, but this is a problem of all the “standard” password schemes (for this I’ll add a TOTP authentication, see at the end)

Password recovery would be handled “manually” (a super-user would have to confirm the identity of the user and then sign the change of the password with the super-user’s key)

Now let’s make it a little more complex: the private key is generated from the PBKDF2 of a salt unique for each user (sent by the server) plus the user’s password. Sadly to make the software compatible with cell phones I will need to keep the iterations of PBKDF2 low (mmmh… On my old Optimus W, 1000 iterations require 8 seconds, while with the S3 it’s nearly instantaneous… But 1000 iterations isn’t very strong) (perhaps I could use Scrypt instead of PBKDF2… It should be more resistant to GPU attacks)

So in the end it would be:

User inserts username and password and press a button. The client asks the server for the salt, for the number of iterations of the hashing function and for the time of the day (this to stop attacks based on reusing the same signature), then calculates the hash of the password by using PBKDF2/Scrypt, regenerates the ECC private key, signs the message (that contains the operation requested and the time of the day received by the server) and sends the signature. The server must remember what challenges he has given and what have been replied (and so are “exhausted”).

After this I could add a two step verification (using the algorithm used by Google Authenticator, for example). The key of this would be shared between user and server. The one-time password could be inserted in the various messages signed by the client. The server could save the calculated time of the TOTP so that it would be easy to verify at a later time.

So the question is: is everything ok? Is there a pre-made solution that does everything? Is there an hole in my reasoning?

2

The DB backend is “insecure”. It is possible to tamper the data (many persons have access to the machine, perhaps it’s “in the cloud”) […]

What I want to be able to do is make very difficult for third parties that have read/write access to the DB machine […]

Your goal shouldn’t be to make it very difficult for third parties to modify the data from your database. Your goal should be to prevent anyone but the administrators to access both the server and the database.

What you are doing right now is like giving your bank account number and password to complete strangers and then ask how you make it difficult for those strangers to take your money. Well, you might think of not sharing the account information in the first place.

It’s also unclear what “in the cloud” has to do with security. Most cloud providers such as Amazon or Microsoft do a great job of hosting virtual machines in a very secure manner.

Therefore:

  • Get rid of those “third parties” who can SSH your server with su access. This is the wrong way of hosting web applications. Don’t do that. And if you do, please, inform your users on the website that all personal information they give you can and will be shared with complete strangers.

  • Use TLS. There are no reasons not to use one, especially since free services exist.

  • Don’t trust client-side. No, you can’t sign JavaScript, and in general, on client-side, you can’t protect your users neither from themselves, nor from any crap they install on their machines. Viruses would be able to inject themselves into a browser and modify JavaScript; if you do a mechanism which checks if JavaScript is tampered, they would be able to tamper the checking mechanism itself.

  • While you can encrypt information on client-side, there are few good reasons limited to few cases where you would actually do it. The reason is that, once again, client machine shouldn’t be trusted, because it’s usually difficult for a user to secure his device. The server, on the other hand, can be secured very easily, and with TLS, man in the middle attacks could effectively be prevented.

Thus, ensure both your servers and the communication between the servers and the clients are secure.

A few notes:

Sadly to make the software compatible with cell phones I will need to keep the iterations of PBKDF2 low […] (perhaps I could use Scrypt instead of PBKDF2… It should be more resistant to GPU attacks)

This is why you need to compute the hash on the server. If you reduce the number of iterations, you’re making it easier for the attacker to bruteforce the hashes.

Searching for a different algorithm is a wrong solution here. Remember that an attacker will have powerful CPUs and GPUs. Your goal is to slow an attacker, and you do that by increasing the iterations.

After this I could add a two step verification (using the algorithm used by Google Authenticator, for example). The key of this would be shared between user and server.

Which means that your “third parties” will have full access to those keys. In this context, two-step verification makes things much worse: it gives you a sense of security, while providing absolutely no benefit.

Since there is no answer, I’ll be bold and propose one, even though I don’t completely understand your constraints.

First, your question contains a mistake. It is not necessary to “buy” a security certificate. StartSSL (offered by StartCom) is free, and Let’s Encrypt (https://letsencrypt.org) is free. There are others, too.

But if you don’t want to use TLS or other certificate-based asymmetric encryption technology to provide your specific form of security, why not do symmetric encryption/decryption using a shared secret?

To share a secret, use the Diffie-Hellman algorithm (but lookup ways to protect against Man-In-The-Middle attacks). An implementation in JS and PHP (TightConnect in github) is available as a demo (http://www.springtimesoftware.com/tightconnect/demo/).

3

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật