Java 機密情報暗号化処理のサンプルコード共有

黄舟
リリース: 2017-03-18 10:22:49
オリジナル
2964 人が閲覧しました

この記事では主に、Java での機密情報の暗号化処理に関する関連知識を紹介します: 1) 機密情報の暗号化処理のために実装したいこと、2) 機密情報の暗号化処理のために行ったこと、3) 機密情報の暗号化を実装する方法。非常に優れた参考値です。以下のエディターで見てみましょう

1. 機密情報を暗号化するときに何を達成したいですか? システムは多くの場合、ユーザーの機密情報を暗号化する必要があり、機密情報が異なれば暗号化要件も異なります。

たとえば、パスワードを暗号化する場合、多くの場合、元に戻せる必要はありません。ユーザーがパスワードを入力すると、システムの暗号化ルールが使用され、暗号化されて保存されたパスワードがエンコード後に直接比較され、その比較結果を取得することで、

ユーザー ログイン

情報の正当性を証明できます。

その後、データベースから削除されることによるデータ漏洩を防ぐために、一部の機密情報 (ID 番号、携帯電話番号など) を暗号化する必要がある場合があります。このようなデータは暗号化する必要があるだけでなく、表示やその他のビジネス シナリオでは完全に表示またはマスクする必要があるため、暗号化されたコンテンツを復号化する必要があります。

2. 機密情報を暗号化するために私が行ったこと

最近、プロジェクトでこの要件を達成するために、いくつかの簡単な設計が行われました:

注: 運用データを維持する際のクエリの利便性を考慮して、aes が使用されます。ここでの暗号化方法、暗号化方法は

mysql

の aes 暗号化結果と同じであるため、SQL で hex 関数と aes_encrypt 関数を直接使用してクエリを実行できます。暗号化ソルトは設定ファイルに保存できます。

1. カスタム アノテーションを使用します。PO の各クラスで暗号化および復号化する必要があるフィールドは、このアノテーションを使用して追加できます。メソッドの実装は Java を使用します。リフレクションとカスタム アノテーション

3. 暗号化および復号化する必要があるすべてのエンティティ オブジェクトは、Base クラスから継承する必要があります

4. エンティティ クラスが暗号化されるときに encrypt メソッドが呼び出され、復号化されるときに decrypt メソッドが呼び出されます。このようにして、オブジェクト内の機密データの暗号化と復号化を実現できます

3. 機密情報の暗号化の実装

まず効果を見てみましょう

注意非常に明確です。最初にオブジェクトの ID 番号を設定し、次に自己暗号化メソッドを実行して独自の参照を返し、オブジェクトの暗号化された JSON 文字列文字列を出力します。自己復号化メソッドを実行して独自の参照を返し、出力します。オブジェクトの復号化された JSON 文字列を出力します。

2. 実装構造を設計する

crypt | |--annotation | |--DecryptFiled | |--EncryptFiled |--crypt | |--EncryptDecryptInterface |--domain | |--BaseInfo | |--SimpleDomain |--utils | |--MySqlUtils
ログイン後にコピー

2.1 アノテーションの実装を見てみましょう

/** * Created by bright on 2017/2/22. * * @author : */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface EncryptFiled { String value() default ""; } 自定义注解
ログイン後にコピー

2 つのアノテーションの実装は一貫しており、アノテーション名が異なるだけです。他のアノテーションのコードは投稿されません。2.2 自己暗号化および自己復号化インターフェイスを定義します

Baseクラスは、このインターフェイスに自己暗号化および自己復号化メソッドを実装します

/** * Created by bright on 2017/2/22. * * @author : */ public interface EncryptDecryptInterface { public  T encryptSelf(); public  T decryptSelf(); } 自定义接口
ログイン後にコピー

2.3 MysqlUtilsの実装

/** * Created by bright on 2017/2/22. * * @author : */ @Component public class MySqlUtils { private static final String ENCRYPTTYPE= "AES";//加密方式 private static final String ENCODING = "UTF-8";//加密时编码 private static String MYSQLUTILSKEY = "aaa";//加密密盐 private static MySqlUtils mysqlUtils;//单例 private static Cipher encryptCipher ;//加密cipher private static Cipher decryptChipher;//解密chipher /** * 该方法可用在spring项目中使用配置文件设置密盐,默认值为123 * @param key */ @Value("${mysql.column.crypt.key:123}") public void setMysqlutilskey(String key){ MySqlUtils.MYSQLUTILSKEY = key; } /** * encryptCipher、decryptChipher初始化 */ public static void init(){ try { encryptCipher = Cipher.getInstance(ENCRYPTTYPE); decryptChipher = Cipher.getInstance(ENCRYPTTYPE); encryptCipher.init(Cipher.ENCRYPT_MODE, generateMySQLAESKey(MYSQLUTILSKEY, ENCODING)); decryptChipher.init(Cipher.DECRYPT_MODE, generateMySQLAESKey(MYSQLUTILSKEY, ENCODING)); } catch (InvalidKeyException e) { throw new RuntimeException(e); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } catch (NoSuchPaddingException e) { throw new RuntimeException(e); } } /** * 单例获取方法实现 * @return */ public synchronized static MySqlUtils getInstance(){ if(mysqlUtils == null){ mysqlUtils = new MySqlUtils(); init(); } return mysqlUtils; } /** * 加密算法 * @param encryptString * @return */ public String mysqlAESEncrypt(String encryptString) { try{ return new String(Hex.encodeHex(encryptCipher.doFinal(encryptString.getBytes(ENCODING)))).toUpperCase(); } catch (BadPaddingException e) { throw new RuntimeException(e); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } catch (IllegalBlockSizeException e) { throw new RuntimeException(e); } } /** * 解密算法 * @param decryptString * @return */ public String mysqlAESDecrypt(String decryptString){ try { return new String(decryptChipher.doFinal(Hex.decodeHex(decryptString.toCharArray()))); } catch (DecoderException nspe) { throw new RuntimeException(nspe); } catch (BadPaddingException nsae) { throw new RuntimeException(nsae); } catch (IllegalBlockSizeException ike) { throw new RuntimeException(ike); } } /** * 产生mysql-aes_encrypt * @param key 加密的密盐 * @param encoding 编码 * @return */ public static SecretKeySpec generateMySQLAESKey(final String key, final String encoding) { try { final byte[] finalKey = new byte[16]; int i = 0; for(byte b : key.getBytes(encoding)) finalKey[i++%16] ^= b; return new SecretKeySpec(finalKey, "AES"); } catch(UnsupportedEncodingException e) { throw new RuntimeException(e); } } } MysqlUtils
ログイン後にコピー
2.4BaseInfoクラスの実装

/** * Created by bright on 2017/2/22. * * @author : */ public class BaseInfo implements Cloneable, EncryptDecryptInterface { /** * 拷贝一个对象,并对新对象进行加密 * 该方法主要用在日志打印上,可防止原对象被加密而影响程序执行 * @param  * @return */ public  T cloneAndEncrypt() { T cloneT = null; try { cloneT = (T) this.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); return null; } if(cloneT !=null) return cloneT.encryptSelf(); throw new RuntimeException("拷贝对象异常"); } /** * 重写clone方法 * @return * @throws CloneNotSupportedException */ @Override protected Object clone() throws CloneNotSupportedException { try { return super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); return null; } } /** * 实现自加密 * * @param  * @return */ public  T encryptSelf() { Field[] declaredFields = this.getClass().getDeclaredFields(); try { if (declaredFields != null && declaredFields.length > 0) { for (Field field : declaredFields) { if (field.isAnnotationPresent(EncryptFiled.class) && field.getType().toString().endsWith("String")) { field.setAccessible(true); String fieldValue = (String) field.get(this); if (StringUtils.isNotEmpty(fieldValue)) { field.set(this, MySqlUtils.getInstance().mysqlAESEncrypt(fieldValue)); } field.setAccessible(false); } } } } catch (IllegalAccessException e) { throw new RuntimeException(e); } return (T) this; } /** * 实现自解密 * * @param  * @return */ public  T decryptSelf() { Field[] declaredFields = this.getClass().getDeclaredFields(); try { if (declaredFields != null && declaredFields.length > 0) { for (Field field : declaredFields) { if (field.isAnnotationPresent(DecryptFiled.class) && field.getType().toString().endsWith("String")) { field.setAccessible(true); String fieldValue = (String)field.get(this); if(StringUtils.isNotEmpty(fieldValue)) { field.set(this, MySqlUtils.getInstance().mysqlAESDecrypt(fieldValue)); } } } } } catch (IllegalAccessException e) { throw new RuntimeException(e); } return (T) this; } } BaseInfo
ログイン後にコピー

2.5 単純なオブジェクト

/** * Created by bright on 2017/2/22. * * @author : */ public class SimpleDomain extends BaseInfo{ @EncryptFiled @DecryptFiled private String id; public String getId() { return id; } public void setId(String id) { this.id = id; } } SimpleDomain
ログイン後にコピー

2.6

public class Client { @Test public void test(){ SimpleDomain sd = new SimpleDomain();//要进行加密解密的实体类 sd.setId("6029131988005021537");//注入身份证号 System.out.println(JSON.toJSONString(sd.encryptSelf()));//执行自加密后输出 System.out.println(JSON.toJSONString(sd.decryptSelf()));//执行自解密后输出 } } Client
ログイン後にコピー
を呼び出してみましょう

以上がJava 機密情報暗号化処理のサンプルコード共有の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!