How to match public key is same or not - digital-signature

I am using crypto.signText() and CAPICOM to sign some text.
so,now i am having is Base64Encoded signed text.
then I am using BouncyCastle to verify the signature. till this it is ok.
now what i want to do is,
when user login into system for 1st time i want to verify that signature and then store publicKey into database. And from next login, i want to match the publicKey strored into database against that user with the newly got signed Text.
if the public key in signed Text and one which is stored in db is same then only user is allow to login into system.
how to implement this? (I am using JAVA lang)

First signatures are created using the private key, not the public key. Afterwards the signature can be verified using the public key. This is what you could do, use the public key from the database and verify the signature of the "signed text". In Java you usually do not need Bouncycastle anymore. The runtime already contains everything you need.
Example how to verify a signature:
http://download.oracle.com/javase/tutorial/security/apisign/vstep4.html
For avoiding replay attacks the "signed text" should contain system time and date or a monotone counter. Therefore the text should also be checked for It's content to be up-to-date.

Related

How to convert id_rsa.pub to id_rsa?

basically my computer bug down earlier and can no longer retrieve my files from my SSD HD.
i have my id_rsa.pub with me since I emailed this to our support team before for me to access the servers.
now I execute this command "ssh-keygen -t rsa" to my computer to generate new pub key.
upon checking the file is inside .ssh and i just replace the id_rsa.pub with the file i have on my email and leave id_rsa as it is.
trying out to access the server but always give me an error "Permission denied (publickey)."
it could be because of id_rsa which is still the latest.
any way i could replace the value based on the pubkey i have?
thanks.
Simply put, no.
The big idea behind public key cryptography is that the private key (in this case, id_rsa) is always hidden and secure, and only one person (or computer) has access to it. The public key (id_rsa.pub) provides just enough information that it is safe for anyone in the world to have access to it. If you could retrieve the original private key from the public key, then your private key would not be secure1.
The new keypair that you generated is totally distinct from your old one. Whatever server you are trying to ssh into is expecting to see the request signed with your old private key. Since you don't have access to it anymore, you can't sign the request with the correct key, and the server is rejecting your ssh attempt with a public key error.
So, basically, because you lost access to your private key, you can no longer ssh using that keypair.
Your administrative team will need to put your new public key onto the server so that you can ssh using the new key.
1 Note: It is theoretically possible to generate a private key that would match an existing public key, but this process is computationally intractable. Digicert estimates that this would take 6.4 quadrillion years for a 2048-bit RSA key.
normally you have a private part of a rsa key and a public one. You spread the public key out to the internet. Now you can sign with the private key you packages or data, and everyone how knows you public key can check if this data or package is from you. So it's possible to generate a public key from a private, but i is impossible to generate a private key out of a public key in a acceptable time. So you need to generate a new one on you computer and need to put the new generated public key on your server, and you will have access again.

Encrypting text

I'm wondering if it's possible to encrypt text client side.
The situation is that I have a block of text I want to encrypt, and then save the encrypted text to a file. Only after a certain amount of time has passed will my program decrypt it. Another requirement I have is to be able to transfer the file with the encrypted text and be able to decrypt it with other copies of my program on various machines.
The problem is where to store the key. The only implementation I can think of that would work is if I store the key server side, and have it return the key after a certain time has passed.
Is there a way to do this client side (i.e. without any internet access)?
You can surely encrypt text on the client side, but the real problem is key management.
If the assumption is no Internet access, then you're going to have to package a certificate in the client that contains both keys, private to encrypt, public to decrypt, unless you use a symmetric key. Was going to suggest just generating a local, temporary symmetric key, but you state you must be able to decrypt the text on other machines that won't have it, so that won't work. At first blush, and maybe I'm overlooking something obvious, is packaging a cert on the client with public and private keys, and that introduces its own set of problems, eg protecting the cert with the private key.

Protecting a file using asymmetric cryptography

I know how asymmetric cryptography works. I know there are two keys (one private and one public).
When someone wants to communicate they exchange their public keys encrypt messages with those public keys AND then the respective message could be decrypted ONLY by the user that has the private key.
Now, I'm using Node.js and I need to do something like this...
I need an application that EACH hour reads a database, extracts data and saves it to a file that I need to send to another server.
My problem is that I DON'T WANT that file will be visible to other, I do the transfer using SSH so there is no problem BUT
I must encrypt that file because I'm not the admin of that server SO maybe someone could read it. Unfortunately the admin is the same for both servers.
So my idea is to encrypt the file with a public key, and then only he who has the private key(me) could decrypt it.
I think it is pointless using something like:
var key = 'blablabla'
If I use a public key, there is no problem, all can read it..... it is public indeed. But with this public key, nobody can decrypt the message, so it is
something like one-way encryption.
Now, could someone tell me if I need a signer/verifier to do this job, OR maybe I have to generate two keys (public/private) with openssl and pass those keys to a cipher/dechiper?
I'm looking at crypto modules, but there are no examples....
In general, your idea is right - you encrypt using public key and decrypt using private key of yours. However, practically the procedure is more complex. Random symmetric key is generated and the data is encrypted using that key. Then the public key is used to encrypt the random key. Encrypted key is sent to recipient together with encrypted data. On the other side encrypted key is decrypted using a private key, then the data is decrypted.
You can use OpenPGP keys or X.509 certificates to do the job.
In case of OpenPGP the standard offers encryption and decryption as atomic procedures (on the user level). In case of X.509 certificates you need to use PKCS#7 / CMS.
OpenSSL library offers operations with PKCS#7 / CMS, however when I look at nodeJS API for OpenSSL, that API is very limited and doesn't expose those functions. Maybe you can write your own nodeJS module which will interface with OpenSSL and provide missing functions.
Another alternative is to use OpenPGP keys and node-gpg module. That module uses gnupg to do the actual job, so gnupg must be installed.
Unfortunately I don't see any other suitable libraries in the 3rd-party module list provided in nodeJS wiki.

Signing and verifying an automatically generated report

Last summer, I was working on an application that tested the suitability of a prospective customer's computer for integrating our hardware. One of the notions suggested was to use the HTML report generated by the tool as justification for a refund in certain situations.
My immediate reaction was, "well we have to sign these reports to verify their authenticity." The solution I envisioned involved creating a signature for the report, then embedding it in a meta tag. Unfortunately, this scenario would require the application to sign the report, which means it would need a private key. Once the application is storing the private key, we're back at square one with no guarantee of authenticity.
My next idea was to phone home and have a server sign the report, but then the user needs an internet connection just to test hardware compatibility. Plus, the application would need to authenticate with the server, and an interested party could figure out what credentials it was using to do that.
So my question is this. Is there any way, outside of obfuscation, to verify that the application did indeed generate a given report?
As Eugene has rightly pointed that my initial answer was to authenticate the receiver. Let me propose an alternative approach for authenticating the sender
authenticate the sender:
When your application is deployed at your client end, you generate and deploy a self signed PFX certificate which holds the private key.
The details of your client and passphrase for the PFX is set by your client and may be you can get it printed and signed by your client in paper to hold them accountable for the keys which they have just generated..
Now you have a private key which can sign and when exporting the HTML report, you can export the certificate along with the report.
This is a low cost solution and is not as secure as having your private keys in a cryptotoken, as indicated by Eugene, in the previous post.
authenticate the receiver:
Have a RSA 2048 key pair at your receiving end. Export your public key to your senders.
When the sender has generated the report, let the report be encrypted by a symmetric key say AES 256. Let the symmetric key itself be encrypted/wrapped by your public key.
When you receive the encrypted report,use your private key to unwrap/decrypt the symmetric key and in turn decrypt the encrypted report with the symmetric key.
This way, you make sure that only the intended receiver alone can view the report.
I'd say that you need to re-evaluate possible risks and most likely you will find them to be not as important as you could think. The reason is that the report has value for you but less likely for a customer. So it's more or less a business task, not a programming one.
To answer your concrete question, there's no simple way to protect the private key used for signing from being stolen (if one really wants to). For more complex solutions employing a cryptotoken with private key stored inside would work, but cryptotoken is itself a hardware and in your scenario it would unnecessarily complicate the scheme.

If public key of two files are same, is it sufficient to conclude that they were signed by the same certificate?

I am implementing an auto-update mechanism for my software. The msi on the server is signed using signtool. My app downloads the msi and reads the public key of the downloaded msi. If the public key matches the one that is hard coded in the source code, it will execute the msi and update itself.
Would this is be sufficient to ensure that no malicious msi gets executed by mistake? My understanding is that a file will have the same public key ONLY if signed by my certificate.
Edit:
With petey's help, I was able to detect if the msi was signed by my certificate or not. However, this didnt quite solve my problem. I can still edit the signed msi using a tool like Orca. Even the msi is no longer the same as the one that was signed, nothing happens to certificate. So when I check whether the msi is signed by me, I get yes. While I understand that this might be intended behaviour, but there must be some way to detect if the msi was tampered with??
Odds are, if it's the same public key, yes it is the same certificate. But with this knowledge an attacker could easily mimic your public key and stick it on his MSI, because, well it's public. You should use that public key to verify the signature on the MSI, not just check if it's the same public key, that way you would be certain it was signed with your corresponding private key, which no attacker would have. You should also run up the cert chain and verify signatures right up to your trusted CA.
Edit:
What exactly are you signing? A signature should not be valid if what was signed is altered. However, it sounds like a Message Authentication Code (keyed hash) would work. If you have a pre-shared hashing key, you could hash the MSI before it is downloaded, then verify the hash again client side. Or if you dont want to use a keyed hash, you could use a regular hash then sign the hash value with that same private key. If you can "verify" (ie decrypt) the hash with the public key, you know that hash came from you, then you can re-hash the msi and check if the hashes are the same.

Resources