【数字安全】Security in Java

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wuzh1230/article/details/51815345

About JCA and JCE

Cryptography Providers

Jurisdiction and Import/Export Policy

Umlimited.Strength.JCE8Policy

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]

X509Certificate

Self.Signed.X509Certificate
Export.X509

Ref

There are a couple of commonly quoted solutions to this problem. Unfortunately neither of these are entirely satisfactory:

Install the unlimited strength policy files. While this is probably the right solution for your development workstation, it quickly becomes a major hassle (if not a roadblock) to have non-technical users install the files on every computer. There is no way to distribute the files with your program; they must be installed in the JRE directory (which may even be read-only due to permissions).

Skip the JCE API and use another cryptography library such as Bouncy Castle. This approach requires an extra 1MB library, which may be a significant burden depending on the application. It also feels silly to duplicate functionality included in the standard libraries. Obviously, the API is also completely different from the usual JCE interface. (BC does implement a JCE provider, but that doesn't help because the key strength restrictions are applied before handing over to the implementation.) This solution also won't let you use 256-bit TLS (SSL) cipher suites, because the standard TLS libraries call the JCE internally to determine any restrictions.

猜你喜欢

转载自blog.csdn.net/wuzh1230/article/details/51815345