We have some Java library performing AES and RSA encryptions (using javax.crypto.Cipher).
A new requirement came in to make the code FIPS 140-2 compliant. Reading some articles what I understood is that I have to change the followings in the java.security file in JDK/JRE and recompile the code. Will that make my library FIPS 140-2 compliant?
#Use these three providers for FIPS compliant
security.provider.1=com.rsa.jsafe.provider.JsafeJCE
security.provider.2=com.rsa.jsse.JsseProvider
security.provider.3=sun.security.provider.Sun
#Disable the below providers for FIPS compliant
#security.provider.1=sun.security.provider.Sun
#security.provider.2=sun.security.rsa.SunRsaSign
#security.provider.3=sun.security.ec.SunEC
#security.provider.4=com.sun.net.ssl.internal.ssl.Provider
#security.provider.5=com.sun.crypto.provider.SunJCE
#security.provider.6=sun.security.jgss.SunProvider
#security.provider.7=com.sun.security.sasl.Provider
#security.provider.8=org.jcp.xml.dsig.internal.dom.XMLDSigRI
#security.provider.9=sun.security.smartcardio.SunPCSC
#security.provider.10=sun.security.mscapi.SunMSCAPI
Is there any other changes I need to perform, like using any special jar, compiling with any argument, etc.?
To be FIPS 140-2 compliant:
You have to use a FIPS 140-2 approved cryptographic modules. It will provides the approved cryptographic implementations. See: https://csrc.nist.rip/groups/STM/cmvp/documents/140-1/140val-all.htm. Read the description and/or the certificate to know the version to use.
For each cryptographic operations (signature, encryption, key establishment, hashing ...) you also have to use approved security algorithms and parameters. Read: https://csrc.nist.gov/csrc/media/publications/fips/140/2/final/documents/fips1402annexa.pdf. The document provides also a lot of references about the configuration of the security functions (key size, elliptic curve, ...).
For your case:
AES128, AES192 or AES256 for encryption, with operation mode GCM, CCM, CTR, CBC, CFB, OFB (Or XTS for storage).
RSA for Key Establishment or Signature with key size of 2048 bits minimum.
Related
I am developing a digital signature java class using the SHA1withRSA algorithm with a 256 bits certificate. But I am getting this error:
Signature length not correct: got 344 but was expecting 256.
I am using the SunJSSE provider (that not implements the SHA256withRSA algorithm) because he uses the PKCS12 keystore type. And I need this, because this is a batch application.
Is the SAH1withRSA algorithm incompatible with 256 bits certificate?
First, you can't possibly have a 256-bit RSA certificate, or key. 256-bit RSA wasn't secure when RSA was published in 1977 much less anytime close to now. That exception says it is looking for a 256 byte signature, which is 2048 bits, implying a key and certificate also of 2048 bits, which is currently (since 2015) the standard and widely used size for RSA.
Second, yes SHA1withRSA technically works with a 2048-bit RSA key (and certificate), although it is less secure. SHA1 was originally rated for only 80-bit strength against collision, and has been broken (at significantly lower cost, about 63 bits) about a year ago -- see https://shattered.io -- making it insecure for signatures in many cases, and thus leading more and more systems, programs, and users to reject SHA1 signatures. For example, all Oracle Java packages from 8u144 up (roughly last summer) have java.security jdk.certpath.disabledAlgorithms configured by default to prohibit use of SHA1-signed certificates in TLS (including SSL, but SSL is also broken and prohibited by default). Java doesn't currently prohibit other uses of SHA1 signatures, but may be changed to. And lots and lots of things you might want to communicate or interoperate with, like browsers, webservers, email systems, repositories, etc, either have already prohibited SHA1 or probably will.
But it isn't necessary. You can use multiple providers in one program, and in particular you can use the KeyStore PKCS12 from SunJSSE while also using the Signature SHA256withRSA (or other SHA2+RSA variants) from SunRsaSign. In fact it's easiest to not specify the provider(s) at all and just let KeyStore.getInstance() and Signature.getInstance() (and the other JCA interface classes) find the correct provider automatically.
Finally, your signature is probably base64-encoded: ceil(256/3)*4=344. Take a look at the data and see if it consists of base64 characters, and if so which set. If it is base64, decode it to binary (i.e. byte[] in Java) and use that. In Java8+ just use java.util.Base64 which supports both variants now common: the 'MIME' variant and the 'URL-safe' (primarily JSON) variant. In older Java you can use javax.xml.bind.DatatypeConverter for MIME, or any number of third-party libraries with varying capabilities.
I've encrypted a file using Bouncy Castle API. I've successfully decrypted that file using the same API.
However I cannot decrypt the file using PGP command line
No error messages are shown but the decrypted file is not being generated:
C:\pgp-cli>pgp arquivo-cripto-cast5-bin.pgp
Pretty Good Privacy(tm) Version 6.5.8
(c) 1999 Network Associates Inc.
Uses the RSAREF(tm) Toolkit, which is copyright RSA Data Security, Inc.
Export of this software may be restricted by the U.S. government.
File is encrypted. Secret key is required to read it.
Key for user ID: contine
2048-bit RSA key, Key ID 0x150AAE5B, created 2015/03/26
Key can sign.
Could it be a compatibility issue?
PGP 6.5.8 is horribly outdated, a lot changed in cryptography since then. There is a bunch of ways to introduce incompatibilities with this old PGP version, and it's hard to tell what exactly is the problem. Since that old version, new ciphers (both symmetric and assymetric), hashing and I think even compression algorithms have been introduced.
If you do not want to buy a newer version, consider using GnuPG which is free and mostly even compatible with PGP's arguments (and probably has much broader usage than the good old PGP, which is owned by Symantec at the moment). A readily built GnuPG package for Windows is available on GPG4Win.
I have seen that AES 256 Encryption Decryption works on Java 6 and above.
How can i achieve the same thing in Java 5 (apart from policy files)
The BouncyCastle library has support all the way back to 1.4. It includes AES256, and as long as you don't use it as JCE provider, I think you can use it without policy files.
That said, the default Java 1.5 JCE (Java Cryptography Extension) does include AES256. As you noted in your question, you would need to deploy an unlimited policy file to actually use the 256-bit algorithm. This is unavoidable, but shouldn't be that difficult. The bouncycastle link above tells you how to do it.
I am currently upgrading an application that generates OpenPGP messages to be FIPS 140-2 compliant. Currently I generate PGP messages that use RSA/AES-256 encryption which are both approved algorithms using BouncyCastle and its OpenPGP provider. I am no longer able to use BouncyCastly since it is not FIPS 140-2 validates, so I am looking at the BSAFE library from RSA.
This library doesn't have the high-level abstraction to let you generate an OpenPGP message directly. Does anyone know of a library that can use an existing JCE provider (like my BSAFE library) capable of generating OpenPGP messages? I'd really like to avoid having to implement the OpenPGP spec myself, as that seems like it would be quite time consuming. Alternatively any suggestions for other ways to format my encrypted files?
Thanks in advance for any input!
After much research it seems that there is no way to do this without implementing the OpenPGP format yourself. However the Cryptographic Message Syntax seems to be a suitable replacement.
There are major differences between S/MIME (Cryptographic Message Syntax) and OpenPGP.
http://mozilla-enigmail.org/forum/viewtopic.php?t=67
Mainly, S/MIME exchanges keys in terms of certificates (which must utilize a certificate authority, limited to 1024 bit, and expires after 1 year), while OpenPGP uses PGP keys (can be exchanged peer-to-peer, or utilize a free keyserver, or host your own keyserver).
FIPS 140-2 doesn't apply to protocols like SSL, PGP, S/MIME, or SSH. Those are security protocols that use cryptographic algorithms like RSA and AES. (Commercial crypto vendors aren't likely to point out this distinction, however).
FIPS 140-2 lists approved algorithms. It also specifies testing criteria for "cryptographic modules" that implement these algorithms. But, it doesn't say anything about the application of these algorithms.
So, you can use BouncyCastle's PGP provider. Instead of installing Bouncy Castle as a crypto-provider, install your FIPS 140-2–certified implementation. Bouncy Castle's PGP will use the preferred crypto provider for its underlying cryptographic algorithms. You can use their S/MIME support in the same way.
I need an java RC5 encryption and decryption algorithm.
The JCE includes support for RC5 but Sun has not implemented RC5 in any of their providers. The Bouncycastle provider, on the other hand, does include RC5. So if you just add the bouncycastle provider you should be able to use RC5 through the JCE (e.g. Cipher c = Cipher.getInstance("RC5/CBC/PKCS5Padding");)
However, just because you can get it for free does not mean you can legally use it for free. For example, in the U.S. you would need to obtain a license from the RC5 patent holder.
EDIT: The RC5 patent has expired in the United States.
The JDK comes with a JCE provider supporting RC5. See http://download.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html and look for the explanations on the Cipher class to get you started.
Also look at the RC5ParameterSpec class.