Bouncy Castle DSA with SHA1 signature verification - java

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.

Related

Can encryption and Digital signatures produce exactly one file?

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

decrypt a file with java(bountycastle maybe? , no zip solutions please)

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.

Android RSA Keypair Generation - Should I use Standard Java/Bouncy Castle/Spongy Castle/JSch/Other?

I've been looking around for about a week+ to implement a method I have in mind. I have came across (and read) many articles on all of these different methods, but I am still left confused, so I was hoping maybe someone can spread their knowledge of these topics so I can more easily go about creating my sought after method and implementing it in Android.
My "sought after" method:
Must generate RSA Public & Private keys
Public must have PKCS#1 padding
Must be RSA 2048
Return Public Key in Byte array
Apparently you can go about it four ways:
Standard Java
Bouncy Castle
Spongy Castle (Android Friendly?)
JSch
Since I'm very new to security and Java as a whole I was wondering if someone could finally give a good clear cut explanation of all of this.
Below are the ways I have tried to implement my sought after method (mentioned above) in the 4 different programming methods. If I don't know something it's because I can't figure out through the respective documentation. Please feel free to correct me.
1. Standard Java (Not sure if PKCS#1):
public byte[] returnPublicKeyInBytes() throws NoSuchAlgorithmException {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(2048);
KeyPair keyPair = kpg.genKeyPair();
byte[] pri = keyPair.getPrivate().getEncoded();
byte[] pub = keyPair.getPublic().getEncoded();
return pub;
}
2. Bouncy Castle (Not yet functional =/ Ideas?):
public byte[] returnPublicKeyInBytes() throws NoSuchAlgorithmException {
RSAKeyPairGenerator r = new RSAKeyPairGenerator();
r.init(new KeyGenerationParameters(new SecureRandom(),4096));
AsymmetricCipherKeyPair keys = r.generateKeyPair();
CipherParameters pri = keys.getPrivate();
CipherParameters pub = keys.getPublic();
byte[] pubbyte = pub.toString().getBytes();
return pubbyte; //NOT WORKING
}
3. SpongyCastle (Havn't started it/Same as Bouncy Castle?):
4. JSch (Very Dis-functional/Work in progress)
public byte[] returnPublicKeyInBytes(JSch jSch) {
try {
KeyPair keyPair = KeyPair.genKeyPair(jSch, KeyPair.RSA);
ByteArrayOutputStream bs = new ByteArrayOutputStream();
keyPair.writePrivateKey(bs);
jSch.addIdentity("Generated", bs.toByteArray(), keyPair.getPublicKeyBlob(), null);
return keyPair.getPublicKeyBlob();
} catch (JSchException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
I'd like this to really become more of a resource for anyone that has problems with RSA key generation in Android (like I, and many others have had).
I feel that Bouncy Castle has very little information about it's API which makes it extremely difficult for a beginner (like me) to understand it. From my research, people use Bouncy Castle in Java instead of the built-in security provider because Bouncy Castle is much more robust. Using Bouncy Castle in Android is not desired because it "ships with a crippled version of Bouncy Castle" which may be prone to errors. Spongy Castle is simply a repackage of Bouncy Castle.
To this end, I will ask my final question of, which method should be used for Android?
Update
I hope someone can answer this later on. As for what I did to solve my problem was to just use NDK.
It is complicated, but I'll try to explain as best I can. I think I'll start with Java. My discussion is geared to Java 6, I'm not sure what has changed in Java 7.
Java' built-in cryptography is available through the Java Cryptography Extension (JCE). This extension has two parts to it, the application API and service provider API. The application API is the part you interact with. You use the getInstance() factory methods of various crypto classes. The service provider aspect is more confusing for the average programmer. They don't care about how the crypto is implemented, they just want something that works. But under the hood there are the crypto provider classes that do the actual work. If you look at the arguments to getInstance() you'll see that you can specify the provider if you want. Why would you ever want to? Maybe you have paid $$$ for an optimized commercial implementation of RSA, so you want to use that one. Perhaps one provider has a FIPS certificate or some other certification that you need for your app. Then you would specify that provider. Sun/Oracle ships their Java environment with several providers that together comprise the default provider set for their Java environment. Don't look at them too carefully because they are overlapping and thus confusing due somewhat to historical artifacts. Basically, when using Oracle Java you ask for some crypto like a KeyPairGenerator through KeyPairGenerator.getInstance("RSA"); you're going to get an appropriate class instance from one of these providers.
Next, lets look at bouncycastle. The bouncycastle library consists of two parts. One is their unique crypto library whose API you have experimented with in your #2 above. The second part is a lot of glue code to allow this library to be used as crypt provider for the JCE. This means you as a programmer have a choice as to how you use the bouncycastle crypto library. You can use their API directly as in #2 above. Or, you can use the JCE api but explicitly specify the bouncycastle implementation by something like KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC");.
If you prefer to use the unique bouncycastle API directly (they call it their "lightweight API") then you have no need for all the glue code used to make it work as a JCE provider. For this bouncycastle does provide a download of just the lightweight API classes.
And now, at last, we look at Android's implementation. Google didn't license Oracle's Java source code, so they didn't have any of Oracle's JCE providers. They had to provide their own providers. Since bouncycastle had all the code needed, and was open source and liberally licensed, Google/Android chose to use bouncycastle as the basis for their default JCE provider. But, Android has made no effort to make available the unique lightweight API for Android programmers. They expect you to use these classes solely through the JCE. They have modified the bouncycastle code to tune it for Android. They fact that you can find and maybe use some of the lightweight API directly on Android is simply a side-effect of the fact that it's there under the hood. And not everything is there. Some have described this situation as "bouncycastle on Android is crippled".
To actually provide a full featured version of the bouncycastle library on Android some developers produced something called the Spongycastle library. It is nothing more than the bouncycastle library modified so that it can work on Android. The chief modification was to change the package names from org.bouncycastle.* to org.spongycastle.* to prevent namespace conflicts.
So what should you use? That depends on what you want to do, what your portability needs are, what your style preferences are, and what you crypto skill level is. In general, when you are using these libraries you are using crypto at fairly low level. You are concentrating at how to do it (use RSA for key transport, use AES for message encryption, use HMAC-SHA256 for message integrity, etc.) versus what to do (I want to send an encrypted message to a recipient via an email-like mechanism). Obviously, if you can you should stick to higher-level libraries that directly solve your problem. These libraries already understand what PKCS#1 is and how to use it as part of larger and more complete protocols.
I was helping somebody earlier today with bouncy castle today. His code does work, so check it out
RSA key pairs generating using bouncy castle. Making code runnable from java program

Java Sun PKCS#11 provider, HSM token LOGIN REQUIRED flag not set and empty list of aliases

I'm Pavel and I'm mainly a Java developer. Here is my problem:
I'm trying to list aliases in HSM slot using Java Sun PKCS#11 provider and I'm getting an empty list. I have tried it with Java 6 and 7 on Windows XP/Server platforms.
I downloaded Sun PKCS#11 sources and examined them, switched on debugging, did other tricks so finally I discovered that the aliases map is empty because the token has LOGIN_REQUIRED flag not set. In Sun PKCS#11 implementation there is one IF construct so when this flag is not set even the PIN bytes are provided to the keystore there is no C_Login call!
I find it is strange! Can someone explain me if it is a bug in Sun implementation of PKCS#11 provider or there is a general idea behind it?
Anyway when I "hack" the original sources so if there is a PIN provided It makes a login op to token no matter if the LOGIN_REQUIRED flag is set or not and I got the aliases from the token!
That's correct, the Sun PKCS#11 provider tries to look for all the private keys that are visible publicly (without logging in) when finding aliases. After that, it will try and find a viable certificate chain for the private keys (first by PKCS#11 ID, then by X509 issuer).
I haven't got a clue why, but it seems to me that the PKCS#11 provider came to live at the same time that the Sparc T1 processor (Niagara) was introduced, which contains a cryptographic processor. There has never been any compatability data provided by Sun/Oracle - I presume their main focus was getting the T1 working within Java - this is however a guess. The only way to know for sure it to ask.
If you want to have a better provider, you can take a look at the IAIK software (whose lower level, open source, implementation is used by Sun/Oracle). They do provide support and compatability statements. This is, however, a commercial product.
Or you can get your patch accepted, I would certainly be interested in an option to login before the available private keys are looked up using PKCS#11 FindObjects. If you file a bug report I will certainly vote for it.

Protect string constant against reverse-engineering

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.

Categories