Javaの下でいくつかの暗号化方式の実現

9643 ワード

最近ずっとこの方面のものをして、先に実現を置いて、原理はゆっくりと補います.
Mavenライブラリ
jdk自体の復号アルゴリズムが不完全であるため、以下の2つのライブラリのサポートを追加する必要があります.
	<dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk16</artifactId>
            <version>1.46</version>
        </dependency>

        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.10</version>
        </dependency>

AES
可逆的なアルゴリズムであって、原文は鍵のセットによって暗号化され、その後、この鍵によって復元されることができる.
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.util.encoders.Hex;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;

public class AESCoder {

    public static final String KEY_ALGORITHM = "AES";

    public static final String CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";

    //    
    private static Key toKey(byte[] key) throws Exception{
        //   DES   
        SecretKey secretKey = new SecretKeySpec(key,KEY_ALGORITHM);
        return secretKey;
    }

    //  
    public static byte[] decrypt(byte[] data,byte[] key) throws Exception{
        //    
        Key k = toKey(key);
        //   
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        //   ,       
        cipher.init(Cipher.DECRYPT_MODE,k);
        //    
        return cipher.doFinal(data);
    }

    //  
    public static byte[] encrypt(byte[] data,byte[] key) throws Exception{
        //    
        Key k = toKey(key);

        //   
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);

        cipher.init(Cipher.ENCRYPT_MODE,k);
        //    
        return cipher.doFinal(data);
    }

    //    
    public static byte[] initKey() throws Exception{

        //   
        KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM);

        //       256
        kg.init(256);

        //      
        SecretKey secretKey = kg.generateKey();

        //      
        return secretKey.getEncoded();
    }

    public static void main(String args[]) throws Exception{

        String str = "AES" ;

        byte[] inputData = str.getBytes();

        System.out.println("  :"+str);

        //     
        byte[] key = AESCoder.initKey();

        System.out.println("  :"+ Base64.encodeBase64String(key));

        //  
        inputData = AESCoder.encrypt(inputData,key);
        System.out.println("   :"+ new String(Hex.encode(inputData)));

        //  
        byte[] outputData = AESCoder.decrypt(inputData,key);

        String outstr = new String(outputData);

        System.out.println(outstr);
    }

}

SHA
MD 4の発展に基づいて不可逆的なhashアルゴリズムのセットが得られた.
import org.bouncycastle.util.encoders.Hex;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class SHACoder {
    //SHA-256    
    public static byte[] encodeSHA(byte[] data){
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            return md.digest(data);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
    }
    //  16      
    public static String encodeSHAHex(byte[] data){
        byte[] b = encodeSHA(data);
        return new String(Hex.encode(b));
    }
}

RSA
非対称暗号化方式であって、鍵は2つのバイナリデータを有し、1つは公開鍵とし、1つは秘密鍵とし、バイナリのデータはそのうちの1つの鍵で暗号化され、その後、別の鍵で復号される.
import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

public class RSACoder {

    public static final String KEY_ALGORITHM = "RSA";

    //    
    private static final String PUBLIC_KEY = "RSAPublicKey";
    //    
    private static final String PRIVATE_KEY = "RSAPrivateKey";

    //RSA    
    //   1024
    //       64 
    //   512 ~ 65536  
    private static final int KEY_SIZE = 1024 ;

    //    
    public static byte[] decryptByPrivateKey(byte[] data,byte[] key) throws Exception{
        //    
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(key);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

        //    
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);

        //     
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());

        cipher.init(Cipher.DECRYPT_MODE,privateKey);

        return cipher.doFinal(data);
    }

    //    
    public static byte[] decryptByPublicKey(byte[] data,byte[] key) throws Exception{
        //    
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);

        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

        //    
        PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);

        //     
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());

        cipher.init(Cipher.DECRYPT_MODE,publicKey);
        return cipher.doFinal(data);
    }

    //    
    public static byte[] encryptByPrivateKey(byte[] data,byte[] key) throws Exception{
        //    
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(key);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

        //    
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);

        //     
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());

        cipher.init(Cipher.ENCRYPT_MODE,privateKey);

        return cipher.doFinal(data);
    }

    //    
    public static byte[] encryptByPublicKey(byte[] data,byte[] key) throws Exception{
        //    
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);

        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

        //    
        PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);

        //     
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());

        cipher.init(Cipher.ENCRYPT_MODE,publicKey);

        return cipher.doFinal(data);
    }

    //    
    public static byte[] getPriavteKey(Map<String,Object> keymap) throws Exception{
        Key key = (Key)keymap.get(PRIVATE_KEY);

        return key.getEncoded();
    }

    //    
    public static byte[] getPublicKey(Map<String,Object> keymap) throws Exception {
        Key key = (Key)keymap.get(PUBLIC_KEY);

        return key.getEncoded();
    }

    //     
    public static Map<String,Object> initKey() throws Exception{
        //        
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);

        //         
        keyPairGen.initialize(KEY_SIZE);

        //     
        KeyPair keyPair = keyPairGen.generateKeyPair();

        //  
        RSAPublicKey publicKey = (RSAPublicKey)keyPair.getPublic();

        //  
        RSAPrivateKey privateKey = (RSAPrivateKey)keyPair.getPrivate();

        //    
        Map<String,Object> keyMap = new HashMap<>(2);

        keyMap.put(PUBLIC_KEY,publicKey);
        keyMap.put(PRIVATE_KEY,privateKey);

        return keyMap;
    }

    public static void main(String args[]) throws Exception{
        //     
        Map<String,Object> keymap = RSACoder.initKey();

        byte[] publickey = RSACoder.getPublicKey(keymap);
        byte[] privatekey = RSACoder.getPriavteKey(keymap);

        System.out.println(Base64.encodeBase64String(publickey));
        System.out.println(Base64.encodeBase64String(privatekey));

        //  

        //    ,    
        String inputstr = "whthomas";
        //  
        byte[] encodedeData1 = RSACoder.encryptByPrivateKey(inputstr.getBytes(),privatekey);
        System.out.println(Base64.encodeBase64String(encodedeData1));

        //  
        byte[] decodedeData1 = RSACoder.decryptByPublicKey(encodedeData1,publickey);
        System.out.println(new String(decodedeData1));

        //    ,    
        //  
        byte[] encodedeData2 = RSACoder.encryptByPublicKey(inputstr.getBytes(), publickey);
        System.out.println(Base64.encodeBase64String(encodedeData2));
        //  
        byte[] decodedeData2 = RSACoder.decryptByPrivateKey(encodedeData2, privatekey);
        System.out.println(new String(decodedeData2));
    }
}

発生する可能性のあるエラー
復号化中にこのエラーが発生する可能性があります
Caused by: java.security.InvalidKeyException: Illegal key size or default parameters

これは、いくつかの法律法規の制限により、jdkソースパケットにおける暗号化の強度が低下するためである.
この問題を解決するには、Oracle Webサイトから圧縮ファイルをダウンロードします.
  • JDK6: http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html
  • JDK7: http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html

  • このパッケージを解凍して、中の2つのjarパッケージ:local_义齿export_policy.jar元Javaインストールディレクトリ{JAVA_HOME}/jre/lib/securityの下にある2つのjarパッケージを置き換えればよい.