How to exchange encryption keys with the customer? - java

My Java app needs to handle encrypted files. This is the workflow:
Customer encrypts files (RSA encryption for example) and uploads them to Amazon S3.
My Java app picks up the files from AS3.
My Java app decrypts the files.
My Java app creates other files using decrypted ones.
My Java app encrypts new files with different key and uploads to AS3.
Customer picks up the files.
Customer decrypts the files.
Amazon S3 provides the Java classes for download/upload, decryption/encryption. This API takes as input java.security.KeyPair. I am unsure how the customer should supply the key to My Java app, so that the app can get the key as java.security.KeyPair?
What would be the proper way to exchange the keys between Customer and App? Which key file format could be used?

Ussually, assymmetric encryption/decryption works like this:
You generate a private/public key pair. The private key should be held secret and should not be sent around etc. The public key can be given to the customer without security concerns.
Now the customer encrypts his files with this public key. The encrypted file can only be decrypted with the private key. So the user can send the file to you (over Amazon S3 in your case).
You receive the file and decrypt it with your private key.
Now you have got a file from the customer. To be able to send back encrypted messages, you need another public/private key pair. This time, the customer must be the only one knowing the private key. He can - for instance - put the public key in his file that he has sent to you. Anyway, somehow you need to get a public key from him. With that key, you encrypt your files and send them to Amazon S3. The user picks them up and decrypts them with his private key.
So, the customer must not give you a java.security.KeyPair, because those contain the private key. It's unsafe to send the private key. But he can send you the public key as a java.security.PublicKey. I think the best way would be to send it to you either within the file he supplies anyway, or within a separate file that he uploads at the same time and besides the supplied file.

The problem is that you don't have a method of distributing trust yet. Fortunately there is one that works reasonably well: TLS. TLS certificates are stored within the browser (and in the JRE, if you require a thick client instead).
Your key pair should be generated locally (or on a secured machine and imported). The private key should be kept safe the whole time. The customer connects to your site using TLS, and downloads your public key. Then the customer uploads the public key of his key pair. This can be performed during some setup/configuration phase.
Now the customer can encrypt files for you, and you can encrypt files for the customer. Note that TLS already provides encryption (confidentiality). So what you have gained is that files are protected during storage, after they have been transported. Once you have trust in the public key (and a trustworthy system) you could send files over plain HTTP.
Adding a signature is pretty important, otherwise anybody can replace the files in storage. Some audit logging is probably required as well, otherwise files may be removed.
Other schemes are possible (I prefer a PGP scheme for file encryption/decryption), but they require out of band communication of the keys. Note that this is just the basic scheme, there are a lot of pitfalls, but working out a specific security architecture for you application is clearly off topic.

Related

Implement sign with digital certificate on spring based web application

I have spring mvc based web application. One of the use cases requires a customer to digitally sign the information that he provides in a form . This signature then gets embedded into a PDF that will be generated on confirmation. How can I implement this in secure manner.
Currently I request the customer to download the PDF and sign it it offline and then upload it again as I do not want them to upload their private keys to the server
Could you please recommend a better approach for the same
The user could provide his private key in the form but it never gets send to the Server. Instead all the other fields of the form are sent to the server, the server then sends back the SHA hash of the generated PDF. Now this hash can be signed locally and the resulting signature can be sent back again to the server and be attached to the PDF.
However most users would never provide their private key in any online form and additionally it is not that easy to create a digital signature inside the form.
So instead you can go for a partial approach where the user just has to sign the SHA hash of the PDF and paste its signature on the next page of the form. So now download / upload is required. I would still make the download of the PDF optional so the user can check if the hash is valid.

How to encrypt documents or restrict their access to users with specific roles in Spring

I am working on a business platform which allows users of different roles to interact with each other based on their roles. the application is built using Spring + WebSecurityConfig based RBAC.
I need to allow users, when uploading documents to the system, to control who is able to open those documents, even if they were downloaded by some one who has access, only people with specific credentials should be able to open those document. Knowing that the documents are Physically saved in the files system.
Is there for example scripts that I can use to encrypt documents with a password, that I can save in my DB and show only to the privileged users? or there are better approaches.
A solution would be create a service to get a shared secret from DB and allow only privileged users to invoke this service. It would be a good idea encrypt the DB field where you store the secret.
With that you could encrypt and decrypt files using any symmetric key algorithm. For example here is a example using AES that only requires javax.crypto API: https://www.mkyong.com/java/java-symmetric-key-cryptography-example/

Where should I store credentials for my java application to access third party services?

Where should I store credentials for my java application to access third party services?
The credentials are not specific per user on my application. They are for accessing a web service my application is consuming. I know enough not to hard code them into my application, but where and how do I store them? I also assume they will need to be encrypted.
.jar file is best way to store all credentials.
Create interface where store your credentials as a final String
convert interface to jar file
Add that jar file in your build path
Implement this interface where u use credentials, and access String object in which u stored credentials.
Db
.properties file
configuration class with constant
Spring have nice functionality with #Value annotation that can auto-magically inject value from .properties file (under resources folder) with a given key.
I use that because in my case I have different key values in multiple app instances and db would require little more complexity, and furthermore I don't make unnecessary queries to db.
On security basis if attacker can read files on your server than he can easily read your db so that don't play a part here. It can be stored in any file on the system.
On the other hand you can have configuration class with
public static final String SECRET_KEY = "someKey"
To build upon #Zildyan's answer, comments and references to other answers.
There are a few options for where to store:
Database
Properties file
Constant (hard coded)
File system (away from application)
As for how to store:
Depending upon sensitivity. Credentials could be stored in plain text (low sensitivity) or should be encrypted (high sensitivity).
It should also be noted that using a combination of encryption and separating the credentials from the source you would restrict internal access to the credentials.
Some examples
a password stored in plain text may be added to source control and read by anyone with access to the source control.
An encrypted password with decryption code would be easily available to anyone able to run the code.
A plain text file stored on the server may be accessible to anyone with access to the server.
An encrypted file stored on the file system may only be accessible to sys admins and the decryption method available to devs.
The same goes for storing in a database and who has access to that database.
JNDI
Per Wikipedia:
The Java Naming and Directory Interface (JNDI) is a Java API for a directory service that allows Java software clients to discover and look up data and resources (in the form of Java objects) via a name.
Your enterprise likely has a JNDI-compatible directory service established. You would ask the sysadmin to include an entry for your particular credentials.
If you are self-administering, then your Java EE (now Jakarta EE) should have a JNDI-compatible server built-in. Learn to configure it, and add the entry for your particular credentials.

How to encrypt data at client side using eToken

I am going to develop an application with Spring framework and JSP as follows:
1) When the client enters any text and presses encrypt button, the data should be encrypted at the client side, but that encryption should be done using eToken.
2) When the client uploads any file it should be stored in encrypted format in a database.
For that I searched on google but didn't find any helpful resources. We are using eToken that contains a key pair using the RSA algorithm. My problem is how to encrypt and decrypt data and files at the client side using eToken?
I am stuck here, please help me ASAP. Thanks.
Assuming that you want to do this via browser, you would need to have an ActiveX or Java applet, which will do the job. The task can not be accomplished using client-side javascript.
We developed similar solution in our SecureBlackbox product, though it works for signing at the moment (we couldn't imagine a real-life use case that would require encryption).
JFYI: To do encryption you don't need a private key but only a public key. Public key can be exported from the token to the computer.

H2 database: how to protect with encryption, without exposing file encryption key

We are using Java + H2 Database in server mode, because we do not want users from accessing database file.
To add more protection to database file, we plan to use AES encryption (add CIPHER=AES to database URL) in case the storage is stolen.
However, each user will also need to supply file protection password when connecting ([file password][space][user password]).
Although users do not have access to database file, knowing the encryption key (file protection password) will make the encryption quite useless.
Any idea to keep the database file secure (encrypted) without exposing file encryption key to users?
Thank you.
There is currently no way to do that within H2.
One solution is to use file system encryption that is independent of H2.
But please note at some point you would have to provide the (database file or file system) password. This could be when starting the server (prompting for the password to be entered manually). Unfortunately, because somebody would have to enter the password, you couldn't fully automate starting the server.
One clever approach I've heard of is to write a simple webservice that blocks all sites but your webapp's server. Use SSL with certificate-based authentication.
This webservice provides the encryption key.
It sounds really stupid since it seems to provide the key without authentication but the certificate-based authentication covers that. It provides encryption of the key during transit (and if you're really paranoid you could use a shared key to wrap the database key). It can only be called from the webapp's server and it's a lot harder to trigger a webservice call than to do SQL injection or even looking at the filesystem.
If your risk model allows it you could even run this webservice on the same box as your webapp.
A second approach, if you have the necessary permissions, is to create a virtual disk. Put the key on the virtual disk.
During startup you mount the virtual disk, read the encryption key, then unmount the virtual disk. In some designs you could drop the operating system permissions that allow you to mount the virtual disk - it would then be literally impossible for an attacker to read the key via your webapp.
This comes from a much older strategy that read sensitive information from a CD-ROM (or even floppy disk). The app would read the key and then eject the media. It works but requires manual intervention to reload the media before the next restart. It also doesn't work in modern environments where servers don't have CD-ROMs, much less floppy drives.

Categories

Resources