Security in Java


About JCA and JCE
Cryptography Providers
Jurisdiction and Import/Export Policy
LatestJCE8Policy
segment from the README of above download
JCE for Java SE 7 has been through the U.S. export review process.  The
JCE framework, along with the various JCE providers that come standard
with it (SunJCE, SunEC, SunPKCS11, SunMSCAPI, etc), is exportable.

The JCE architecture allows flexible cryptographic strength to be
configured via jurisdiction policy files. Due to the import
restrictions of some countries, the jurisdiction policy files
distributed with the Java SE 7 software have built-in restrictions on
available cryptographic strength. The jurisdiction policy files in this
download bundle (the bundle including this README file) contain no
restrictions on cryptographic strengths.  This is appropriate for most
countries. Framework vendors can create download bundles that include
jurisdiction policy files that specify cryptographic restrictions
appropriate for countries whose governments mandate restrictions. Users
in those countries can download an appropriate bundle, and the JCE
framework will enforce the specified restrictions.

You are advised to consult your export/import control counsel or
attorney to determine the exact requirements.

Open Source BouncyCastle
source
Test and Check
BouncyCastle
Architecture[edit]
The Bouncy Castle architecture consists of two main components that support the base cryptographic capabilities. These are known as the 'light-weight' API, and the Java Cryptography Extension (JCE) provider. There are further components that are built upon the JCE provider which support additional functionality such as PGP support, S/MIME and similar.

The low-level, or 'light-weight', API is a set of APIs that implement all the underlying cryptographic algorithms. The APIs were designed to be simple enough to use if needed, but provided the basic building blocks for the JCE provider. The intent is to use the low-level API in memory constrained devices (JavaME) or when easy access to the JCE libraries is not possible (such as distribution in an applet). As the light-weight API is just Java code, the Java virtual machine (JVM) does not impose any restrictions on the operation of the code, and at early times of the Bouncy Castle history it was the only way to develop strong cryptography that was not crippled by the Jurisdiction Policy files which prevented any JCE providers from performing "strong" encryption.

The JCE-compatible provider is built upon the low-level APIs. As such, the source code for the JCE provider is an example of how to implement many of the "common" crypto problems using the low-level API. Many projects have been built using the JCE provider, including an Open Source Certificate Authority EJBCA.

Difference in EXT
Geek will choose bcprov-ext-jdk15on-154.jar, but i am not a Geek.
a Algorithm called NTRU, is included in ext library, not in regurlar library;
NOTE: all released JARs is already signed by certificate of The Legion of the Bouncy Castle, issued by JCE Code Signing CA.
D:\workspace\tarballs>jarsigner --verify --certs --verbose bcprov-ext-jdk15on-154.jar

s     376698 Tue Dec 29 12:46:12 CST 2015 META-INF/MANIFEST.MF

      [         12/29/15 9:46 AM]
      X.509, CN=The Legion of the Bouncy Castle, OU=Java Software Code Signing, O=Sun Microsystems Inc
      [       12/13/12 3:24 AM 12/17/17 3:24 AM]
      X.509, CN=JCE Code Signing CA, OU=Java Software Code Signing, O=Sun Microsystems Inc, L=Palo Alto, ST=CA, C=US
      [       4/25/01 3:00 PM 4/25/20 3:00 PM]
      [CertPath    : Path does not chain with any of the trust anchors]

      357191 Tue Dec 29 12:46:14 CST 2015 META-INF/BCKEY.SF
        5864 Tue Dec 29 12:46:14 CST 2015 META-INF/BCKEY.DSA
           0 Tue Dec 29 12:44:54 CST 2015 org/
           0 Tue Dec 29 12:44:54 CST 2015 org/bouncycastle/
           0 Tue Dec 29 12:44:54 CST 2015 org/bouncycastle/asn1/
           0 Tue Dec 29 12:44:54 CST 2015 org/bouncycastle/asn1/anssi/
           0 Tue Dec 29 12:44:54 CST 2015 org/bouncycastle/asn1/bc/
           0 Tue Dec 29 12:44:54 CST 2015 org/bouncycastle/asn1/bsi/
           0 Tue Dec 29 12:44:54 CST 2015 org/bouncycastle/asn1/cmp/
bcprov is typically the library you want.

bcprov-ext includes some obscure crypto algorithms that haven't been part of the main release since v1.4.0.

This is briefly explained on the latest releases page:

From release 1.40 some implementations of encryption algorithms were removed from the regular jar files at the request of a number of users. Jars with names of the form *-ext-* still include these (at the moment the list is: NTRU).
NTRU seems to be this algorithm. Personally I'd never heard of it before...
  • Soucre code
  • package com.bitbaba;
    
    import java.io.UnsupportedEncodingException;
    import java.security.InvalidKeyException;
    import java.security.NoSuchAlgorithmException;
    
    import javax.crypto.BadPaddingException;
    import javax.crypto.IllegalBlockSizeException;
    import javax.crypto.NoSuchPaddingException;
    
    /** * @author Administrator * */
    public class CryptoTester {
    
        /** * @param args * @throws NoSuchPaddingException * @throws NoSuchAlgorithmException * @throws InvalidKeyException * @throws UnsupportedEncodingException * @throws BadPaddingException * @throws IllegalBlockSizeException */
        public static void main(String[] args){
            // TODO Auto-generated method stub
    
            String input= "helloworld";
            String pass = "passphrase";
            java.security.SecureRandom random = new java.security.SecureRandom(pass.getBytes());
            javax.crypto.KeyGenerator keyGenerator = null;
            try {
                keyGenerator = javax.crypto.KeyGenerator.getInstance("AES");
            } catch (NoSuchAlgorithmException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            keyGenerator.init(256, random);
            javax.crypto.SecretKey key = keyGenerator.generateKey();
            byte [] keyBytes = key.getEncoded();
            javax.crypto.spec.SecretKeySpec keySpec = new javax.crypto.spec.SecretKeySpec(keyBytes, "AES");
            javax.crypto.Cipher ciper = null;
            try {
                ciper = javax.crypto.Cipher.getInstance("AES");
            } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            try {
                ciper.init(javax.crypto.Cipher.ENCRYPT_MODE, keySpec);
            } catch (InvalidKeyException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            byte[] result = null;
            try {
                result = ciper.doFinal(input.getBytes("utf-8"));
            } catch (IllegalBlockSizeException | BadPaddingException | UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println(result);
        }
    
    }
    
  • Check providers
  • /** * Bouncy Castle provider test */
    java.security.Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
    
    java.security.Provider [] providers = java.security.Security.getProviders();
    for(int i = 0; i < providers.length; i++){
        java.security.Provider provider = providers[i];
        System.out.println(provider.getName());
    }

    output
    SUN
    SunRsaSign
    SunEC
    SunJSSE
    SunJCE
    SunJGSS
    SunSASL
    XMLDSig
    SunPCSC
    SunMSCAPI
    BC
  • Test with default JCE

  • Use default JRE & JDK (version 1.8), and try encrypt with 256bits key. throwing errors as following:
    java.security.InvalidKeyException: Illegal key size or default parameters
        at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1026)
        at javax.crypto.Cipher.implInit(Cipher.java:801)
        at javax.crypto.Cipher.chooseProvider(Cipher.java:864)
        at javax.crypto.Cipher.init(Cipher.java:1249)
        at javax.crypto.Cipher.init(Cipher.java:1186)
        at com.bitbaba.CryptoTester.main(CryptoTester.java:54)
    
  • Test with BC(BouncyCastle) JCE
  • /** * */
    package com.bitbaba;
    
    import java.io.UnsupportedEncodingException;
    import java.security.InvalidKeyException;
    import java.security.NoSuchAlgorithmException;
    import java.security.NoSuchProviderException;
    
    import javax.crypto.BadPaddingException;
    import javax.crypto.IllegalBlockSizeException;
    import javax.crypto.NoSuchPaddingException;
    
    /** * @author Administrator * */
    public class CryptoTester {
    
        /** * @param args * @throws NoSuchPaddingException * @throws NoSuchAlgorithmException * @throws InvalidKeyException * @throws UnsupportedEncodingException * @throws BadPaddingException * @throws IllegalBlockSizeException */
        public static void main(String[] args){
            // TODO Auto-generated method stub
    
            /** * Bouncy Castle provider test */
            java.security.Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
    
            java.security.Provider [] providers = java.security.Security.getProviders();
            for(int i = 0; i < providers.length; i++){
                java.security.Provider provider = providers[i];
                System.out.println(provider.getName());
            }
    
    
            String input= "helloworld";
            String pass = "passphrase";
            java.security.SecureRandom random = new java.security.SecureRandom(pass.getBytes());
            javax.crypto.KeyGenerator keyGenerator = null;
            try {
                keyGenerator = javax.crypto.KeyGenerator.getInstance("AES");
            } catch (NoSuchAlgorithmException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            keyGenerator.init(256, random);
            javax.crypto.SecretKey key = keyGenerator.generateKey();
            byte [] keyBytes = key.getEncoded();
            javax.crypto.spec.SecretKeySpec keySpec = new javax.crypto.spec.SecretKeySpec(keyBytes, "AES");
            javax.crypto.Cipher ciper = null;
            try {
                try {
                    ciper = javax.crypto.Cipher.getInstance("AES", "BC");
                } catch (NoSuchProviderException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            try {
                ciper.init(javax.crypto.Cipher.ENCRYPT_MODE, keySpec);
            } catch (InvalidKeyException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            byte[] result = null;
            try {
                result = ciper.doFinal(input.getBytes("utf-8"));
            } catch (IllegalBlockSizeException | BadPaddingException | UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println(result);
        }
    
    }

    but still failed
    java.security.InvalidKeyException: Illegal key size or default parameters
        at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1026)
        at javax.crypto.Cipher.init(Cipher.java:1245)
        at javax.crypto.Cipher.init(Cipher.java:1186)
        at com.bitbaba.CryptoTester.main(CryptoTester.java:72)
  • Test with BouncyCastle Low-Level Crytpo APIs

  • skipped,
  • Test with Unlimited strength policy file

  • Note: remember to install Policy Files into the CORRECT position of running JVM.
    e.g. If you JVM is at “C:\Program Files (x86)\Java\jre1.8.0_72\bin\javaw.exe”, install Policy Files into “C:\Program Files (x86)\Java\jre1.8.0_72\lib\security”
    Testing with BC passed, Default JCE from SUN etc passed too.
    Result of AES(“hellworld”, “passphrase”) is, you can check it too.
    [14, -66, 43, 83, 79, 45, 38, -5, -112, -43, 117, -5, 54, 51, 115, 31]