I am trying to encrypt a file in Java using AES and then Digitally sign it and store it in a database, so that I can verify the signature and then decrypt it when I fetch that file. I have gone through Oracle's tutorial on digital signature but they create 3 files in the end, namely : Data, Signature & Public key. I am looking for a solution where I only get one file. Does any such kind of solution exist? I am new to cryptography so couldn't gather much information about it.
That is of course possible. If you just concatenate the results (possibly proceded by a length indicator to keep them appart) then you would already have synthesized such a single blob, which can be stored in a file.
That would of course not be a very well described stucture. In cryptography there are already structures defined that do this. Outside the many structures defined for libraries such as RNCrypt there are two well known container formats: CMS and PGP. CMS or Cryptographic Message Syntax was described for SMIME originally and has evolved from the PKCS#7 standard by RSA. OpenPGP is used by applications such as PGP and GPG.
For Java both PGP and CMS functionality is provided by the Bouncy Castle libraries.
It depends on your situation but you would only need a public key signature if all of the following things are true. You want to:
run multiple versions of your AES encryption engine in different places
then need to be able to verify which server encrypted which files
while protecting against a man in the middle attack during this check
This is quite a rare scenario and I would suggest that you dont really need a public key signature.
Normally you would simply append a HMAC "signature" to authenticate the file. I am calling it a signature because it is a kind of signature in the sense that it uses the symmetric AES encryption/decryption key and the encrypted file contents to generate the code. This will protect the integrity of the file from modification by people that dont know the encryption/decryption key.
If you are encrypting files using AES, I suggest using this free open source file format. There is a JAVA library available on the download page.
Yes: you can simply concatenate the resulting files into one (using separators so you can split them again).
Or you can put them all together into a zip file and extract them before processing.
oops missed the database part: there you can store the info either as ascii encoded varchar or directly read the resulting files into BLOBs
Related
I have an APP (Android) and a service made in PHP.
I send information between them and now there is a security problem that I need to encrypt the data very much.
I need to encrypt in java and when I get to the service (PHP) I need to decrypt the content that has arrived.
Is there any native function in JAVA and PHP that already does this?
I found some examples in Google and here in stackoverflow, but nothing that I described in PHP
Ok, 1st if you consider encryption or decryption depends on any specific language or vice-versa, then It's not true. Any encryption/decryption is a concept which available in all languages and surely support by one another.
Now come to your question, as far as I can understand your question, you are looking for approach which encrypt data in JAVA and decrypt same in PHP. Please correct me if I m wrong.
Below I am sharing process/approach which may help you to design/setup your architecture about it.
1) Let's assume you are aming to implement MD5 encryption/description in your application.
2) In java you can achieve all publicly available encryption either inbuilt or by third party jars, just create utility class and create separate bean with required fields, then add required logic in utils class and pass same information to bean.
3) Now Pass that bean data to web-api which is written in PHP (method you prefer get/post), most of the time in PHP it is String only.
4) Inside PHP code pass that information in fashion which describe in below link:
Encp/Decp in php
And in the end just follow below answer, I guess it is bit close to what you are looking for.
Note: I use MD5 just to explain how to setup an architecture and kick-off for base, but in real environment avoid using MD5 as now n-number way available to bypass this one, best use some strong encpy/decpy technique/algorithm like triple DES, RSA, AES etc.
Java and Php relation for encp/decpt
My project is using signature verification of some datasets which come from certain third-party software. Signature algorithm used is SHA1withDSA. When I was using standard SUN crypto provider, that comes with SDK, all went fine. Recently I switched to Bouncy Castle 1.50, and after that some of datasets which previously (that is, with SUN
provider) stood verification, began to fail it, while the rest is still verified OK.
I explored source codes of both providers, and it turned out that SDK's default provider has some sort of protection from incorrectly formed signatures (while capable of being recovered), and Bouncy Castle provider does not have it. Check out
OpenJDK
for Java 7 (lines 336-344) or
OpenJDK
for Java 8 (lines 265-273): there they have made some signature fix in certain case. Whereas there is no such thing done for org.bouncycastle.jcajce.provider.asymmetric.dsa.DSASigner#engineVerify, moreover, in org.bouncycastle.crypto.signers.DSASigner#verifySignature it is explicitly stated that numbers must be positive, otherwise verification fails straight away.
Is it a bug in BC, or is there something that I missed? To overcome
this, I have subclassed org.bouncycastle.crypto.signers.DSASigner and
added there the same aforementioned signature fix, then plugged this
in as yet another signature algorithm (through subclassing org.bouncycastle.jcajce.provider.asymmetric.dsa.DSASigner). But maybe there is another way that I overlooked, and this "issue" is well-known? Please advise.
If the incorrect BER/DER encoding of ASN.1 integers - which are stored as signed big endian, right aligned octets - is indeed the culprit then Bouncy does not have a bug. Positive values should be left padded with a 00 valued byte if the first bit of the encoding is set, otherwise it would represent a negative value.
The Sun provider is wrong to allow those kind of signatures to verify, and the other party is of course generating invalid signatures. Note that it is possible to let the signatures verify without this "fix" within the Sun code: simply adjust the encoding before feeding it to the verification function.
The only time when this is not possible is when the DSA verification is called as a generic signature verification method from another library instead of from an application that can adjust the data before the call.
On the other hand, I think you've created an elegant fix. The only issue with it is that it may not run if the provider's signature is verified from a JCA compliant framework. The other possible fix is to re-encode before feeding it into the Signature class for verification.
Note that I don't see how this could be a security issue; the signature consists of the values of R and S, and it does not matter how they are encoded, as long as you receive the correct values in the end.
I am searching for a way to encrypt a binary file and decrypt the file (probably with javacode) later to make use of it. I only want to decrypt it in Java itself because if it's get decrypted on my local drive, the security is gone...
Is this possible with bouncycastle?
Is bouncycastle api hard to work with? (I know java basics)
Does it need to be decrypted if you want to make use of the file?
Strangely formulated question but:
yes of course you can encrypt/decrypt data in java
yes bouncy castle can do it but you can also do it without bouncy castle
bouncy castle is an awesome library but can be rather complex to work with
yes you can perform the encryption/decryption entirely in memory though you should consider whether or not your swap is encrypted as well, otherwise it won't matter
Do you want PBE (password-based encryption)? I would assume so otherwise you need to consider other aspects like how/where to save the keys.
In short: security is hard.
I have android application that has hard coded (static string constants) credentials (user/pass) for sending emails via SMTP.
The problem is that .dex file in .apk can be easily reverse-engineered and everybody can see my password.
Is there a way how to secure these credentials, while i will still be able to use them in my classes?
We can use "jni module" to keep 'Sensitive Hardcoded Strings' in the app. when we try to reverse engineer APK file we get lib folder and .so files in respective process-folders. which can not decrypt.
You can save your string obfuscated by AES.
In Licensing Verification Library you can find AESObfuscator. In LVL it is used to obfuscate cached license info that is read instead of asking Android Market to find out application is licensed or not. LVL can be downloaded as component of SDK.
I guess you can try a code obfuscator, but really that won't make your password 100% secure and I don't know how well it goes along with the android compiler. Why not use a secured web authentication , like that of Google?
Hashing is not possible since it is not two way.
Any encryption such as AES, DES, blowfish, etch is not a viable solution as you have to include the decryption part within your app and that can be decompiled with a combination of apktool, dex2jar and JD (java decompiler) which is a very powerful combo while decompiling any apk.
Even code obfuscators don't do anything except make life a little more difficult for the decompiling guy, who'll eventually get it anyways.
The only way which I think would work to an extent would be to host the credentials on a server which only your application can access via a web-service call through a separate authentication of some kind - similar to FB's hash key thing. If it works for them, it should work for us.
I was looking into a similar problem and came across this useful thread:
http://www.dreamincode.net/forums/topic/208159-protect-plain-string-from-decompilers/
I'm not too familiar with Android development, but the same ideas should apply.
doing these would be useful:
1- you can encrypt them and obfuscate the encrypting algorithm. any encryption along with obfuscation (progaurd in Adnroid) is useful.
2- you better to hardcode your strings as byte array in your code. many reverse engineering applications can get a list of your hardcoded strings and guess what they are. but when they are in form of byte array they are not readable. but again Proguard is necessary. (it only hides from RAM string constant searching and they are still searchable from .class file)
3- using C++ code to host your constant is not a bad idea if you encrypt them before hardcoding and decrypt them using C++ code.
there is also a great article here :
https://rammic.github.io/2015/07/28/hiding-secrets-in-android-apps/
If you do not have the means to do a web authorization you will need to include the third party decryption with you application.
This is what you could try
1) Write a standalone program only to create a password hash one time. (This program should not be a part of your app). Make a note of the hash that was generated.
http://www.mindrot.org/projects/jBCrypt/
// Hash a password for the first time.
String hashed = BCrypt.hashpw(password, BCrypt.gensalt(12));
2) Store this password hash as a String constant in you APK.
3) Then every time you need to check the password, compare with the hashed password, using bcrypt.
// Check that an unencrypted password matches one that has
// previously been hashed
if (BCrypt.checkpw(candidate, hashed))
System.out.println("It matches");
else
System.out.println("It does not match");
jBCrypt is a single java file and it can be directly included in your application. It is considered one of the strongest encryption algorithms for passwords.
Even through the decryption algorithm is present in you APK, trying to break this is very time consuming details of which can be read in the article below.
Read this article for details and security of bcrypt.
http://codahale.com/how-to-safely-store-a-password/
Again, use this only if you do not have the means to do web based authentication.
Use some kind of trivial encryption or cipher that only you (and your code) understand. Reverse the string, store it as array of integers where you need to take the mod of 217 or something silly to find the real password.
One way you can 100% secure you hard-coded string.
Firstly don't use pro-guard use allatori
Link: http://www.allatori.com/
And secondly don't take you hard coded string in any variable just use that string like this:
if(var=="abc"){}
"abc" is exampled hard coded string.
Allatori fully obfuscate all string that are used in code like above.
Hope it will help for you.
We use Tomcat for our java web application. There is a properties file under WEB-INF folder.
AES encryption will be used to generate key and encrypt password. The encrypted password will be stored in the properties file. Where should be the encryption key stored? Is it a good idea to put the key and the encrypted password in the same properties file? Or should the key be stored outside of the 'webapps' directory?
On windows, you can use the Registry and DPAPI. Using the registry does suck, but its a necessary pain if you want to go for absolute security, and leverage the Operating System to store valuable data.
On other OS X, you can make use of the Keychain.
On linux, I would use file permissions to secure the file.
What you are proposing:
Is it a good idea to put the key and the encrypted password in the same properties file?
Is like storing your money in a safe, then writing the combination to the safe on a stickynote and sticking the note on the safe. All you've done is inconvienced the thief, but not added any meaningful level of security.
If the property file is secure enough to house an encryption key, then you can store passwords in it, in plaintext.
Have you considered the KeyStore class in the Java API. It's a part of Sun's Java Cryptography Architecture.
I have following suggestions,
Don't store the key in the WAR. We leave the responsibility of securing the key to each installation. On production, we can actually secure it by storing the key files on a smartcard.
Make sure your keys are versioned so you can rotate it regularly.
Store pass-phrases to generate the key, instead of the raw key material. This makes it easier to add new keys (you don't have to worry about algorithm or keysize etc). It also adds some obscurity.