I'm exploring an option to store encrypted data to S3. My backend is build with Java and I'm already using JetS3t library for some simple S3 storage manipulations. So, my question is: How to use JetS3t with S3's Server Side Encryption with customer-provided keys (SSE-C) to store files in encrypted format on S3?
I tried to look through the Programmer's Guid for JetS3t but didn't find anything concrete in that regards.
According to the docs here http://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html, you need to add the following headers in your request:
x-amz-server-side-encryption-customer-algorithm Use this header to specify the encryption algorithm. The header value must be "AES256".
x-amz-server-side-encryption-customer-key Use this header to provide the 256-bit, base64-encoded encryption key for Amazon S3 to use to encrypt or decrypt your data.
x-amz-server-side-encryption-customer-key-MD5 Use this header to provide the base64-encoded 128-bit MD5 digest of the encryption key according to RFC 1321. Amazon S3 uses this header for a message integrity check to ensure the encryption key was transmitted without error.
If you use the Amazon Java SDK, doing this is easy and examples are provided in their documentation. But to do so using JetS3t, you can do the following:
Assuming s3Object is the object you are trying to put on S3, call the following for each of the above mentioned headers with appropriate values.
s3Object.addMetadata("<header>", "<header_value>")
Related
I am using vfs s3 plugin to perform file related operation in S3.
Official guide for Server-Side Encryption with Customer-Provided Encryption Keys (SSE-C) is here http://docs.aws.amazon.com/AmazonS3/latest/dev/sse-c-using-java-sdk.html but I am using vfs s3 plugin.
I have checked code of copyFrom method in S3FileObject in com.intridea.io.vfs.provider.s3 package but I didn't found any code to implement Server-Side Encryption with Customer-Provided Encryption Keys (SSE-C) There is option for set
Server Side Encryption but how can achieve it with Customer-Provided Encryption Keys
Is there only way to modify code of s3 plugin? or there is any other way to do the same
Right now it is not possible to use customer-provided encryption keys with vfs-s3 library but I can take your PR or need some time to implement it - you are first one who have asked for it.
I have Used Spring Security Crypto Module for data encryption . Now I want To Search these encrypted data from the database.But I am not getting any idea how do i search.Please Post something if you already faced that type of problem.
You'll have to decrypt it first. You cannot search encrypted data unless you've deliberately chosen homomorphic encryption and you haven't. Note that homomorphic encryption isn't used too much in practice. Normally encrypted data should be indistinguishable from random.
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.
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.
I need to connect to an external webservice from my Java application running on Tomcat 6. I have an SSL certificate for my domain purchased and installed on my server. Now I need to connect to an external service and use my certificate private key to digitally sign any data going to the service using SHA-256 hash and 128-bit salt length. How can I use the private key to create this signature? Can I pick any values for the salt? Will they be able to decrypt it using my public key from the SSL certificate?
Can I use the Bouncy Castle library for this? Any code or tutorials on the subject would be appreciated.
The JCA documentation provides an example for using Signature (under Generating and Verifying a Signature Using Generated Keys. You'd use SHA256withRSA instead of SHA1withDSA, as it's supported by the SunRsaSignProvider (assuming it's an RSA key). You shouldn't need BouncyCastle for this.
If you want to use BouncyCastle, you'd need to do something along these lines (I've haven't tried this particular code):
AsymmetricKeyParameter keyParam = PrivateKeyFactory.createKey(...);
// You might need to cast to private key to RSAPrivateKey
// and get its attributes manually here.
SHA256Digest digest = new SHA256Digest();
RSADigestSigner signer = new RSADigestSigner(digest);
signer.init(true, keyParam);
signer.update(... data to sign, start, length, ...);
byte[] signature = signer.generatedSignature();
(If you're doing this from within a webapp, you'd also need the webapp to be able to gain access to this private key, which may be a security risk should the webapp be compromised. It might be worth considering using a different key/certificate, even self-signed, if the remote party is willing to accept it.)
I would highly recommend using a webservice stack for this:
For eg. an approach for WS-Security client using Apache CXF - http://cxf.apache.org/docs/ws-security.html
One more good reference: http://www.jroller.com/gmazza/entry/cxf_x509_profile