この記事は、に抜粋された「春の雲の戦闘と高度なマイクロ・サービス」の本。
このように敏感な設定パスワードなどの多くの重要な構成情報の一部は、私たちは、セキュリティを確保するために、ストレージの暗号化を設定したいです。あなたは二つの方法でデータ暗号化機能を実現したい場合は、アポロの枠組み自体がデータ暗号化機能を提供していない、最初は、第二は、サードパーティのフレームワークに基づいて、比較的簡単であり、暗号化と復号化ロジックを高め、アポロ・ソースを変更することですデータを復号化します。
jasyptスプリング・ブートフレームワークを開発した春のブートに基づいており、プロパティが自動的に暗号化されたコンテンツを復号化することができ、それは、データの暗号化と復号動作を実行するためのフレームワークによってアポロjasypt-春ブートであってもよいです。
jasyptスプリング・ブートGitHubのアドレスします。https://github.com/ulisesbocchio/jasypt-spring-boot
我々は提供jasyptスプリング・ブートによって暗号化された暗号化方式を設定する必要があります、その後、プロジェクトが開始アポロ、内の暗号化されたコンテンツ構成は、jasyptスプリングブート構成はなるように、暗号化されたアポロの暗号化を解除します復号化の後にコンテンツにアクセスするユーザー。
アポロとjasyptの依存性を追加し、新しいMavenプロジェクトを作成します。
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client</artifactId>
<version>1.1.0</version>
</dependency>
<!--jasypt加密-->
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>1.16</version>
</dependency>
次の追加依存関係の情報:
server.port=8081
app.id=SampleApp
apollo.meta=http://localhost:8080
apollo.bootstrap.enabled=true
apollo.bootstrap.namespaces=application
jasypt.encryptor.password=yinjihaunkey
- jasypt.encryptor.password:暗号化キーを設定します
暗号化ツールは、暗号化の設定のためのクラスを作成します。
public class EncryptUtil {
/**
* 制表符、空格、换行符 PATTERN
*/
private static Pattern BLANK_PATTERN = Pattern.compile("\\s*|\t|\r|\n");
/**
* 加密Key
*/
private static String PASSWORD = "yinjihaunkey";
/**
* 加密算法
*/
private static String ALGORITHM = "PBEWithMD5AndDES";
public static Map<String, String> getEncryptedParams(String input) {
//输出流
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(1024);
PrintStream cacheStream = new PrintStream(byteArrayOutputStream);
//更换数据输出位置
System.setOut(cacheStream);
//加密参数组装
String[] args = {"input=" + input, "password=" + PASSWORD, "algorithm=" + ALGORITHM};
JasyptPBEStringEncryptionCLI.main(args);
//执行加密后的输出
String message = byteArrayOutputStream.toString();
String str = replaceBlank(message);
int index = str.lastIndexOf("-");
//返回加密后的数据
Map<String, String> result = new HashMap<String, String>();
result.put("input", str.substring(index + 1));
result.put("password", PASSWORD);
return result;
}
/**
* 替换制表符、空格、换行符
*
* @param str
* @return
*/
private static String replaceBlank(String str) {
String dest = "";
if (!StringUtils.isEmpty(str)) {
Matcher matcher = BLANK_PATTERN.matcher(str);
dest = matcher.replaceAll("");
}
return dest;
}
public static void main(String[] args) {
System.out.println(getEncryptedParams("hello"));
}
}
mainメソッドを実行し、次の出力を得ることができます。
{input=0JK4mrGjPUxkB4XuqEv2YQ==, password=yinjihaunkey}
入力は、暗号化ハロー後のコンテンツである、アポロ、特定の規則に従う必要があるジョブの保存形式の入力に格納された値をコピーします。
test.input = ENC(0JK4mrGjPUxkB4XuqEv2YQ==)
彼らはこの値を復号化するためにのみjasyptますように、私たちは、ENC暗号化されたコンテンツを使用する必要があります。
局所注射の構成は、たとえば、名前によって直接使用することができます。
@Value("${test.input}")
private String input;
入力値が復号化後の値であり、ユーザは、復号ロジック、取引の枠内jasypt心配する必要はありません。
jasypt統合アポロはまた、いくつかの欠陥を持っている今、私は次の質問を発見しました:
ハブは値を変更した後、プロジェクトの値が更新されません
- 得られた注射Configオブジェクトの値を復号化することができません
@ApolloConfig
private Config config;
@GetMapping("/config/getUserName3")
public String getUserName3() {
return config.getProperty("test.input", "yinjihuan");
}
二つの問題は、暗号化されたパスワードデータベースは一度だけ、唯一の適切な方法も可能であるなど、起動時に復号化することができることを意味し、関係があり、jasypt実装して、上記の、そしてより多くのいくつかの場合コアサービスの構成が暗号化される必要があり、その後、jasyptはあなたがリアルタイムの更新を行うことができない、サポートされていません。次章で私はこの2つの問題を解決するアポロにソースコードを変更する方法を説明します。
アポロ拡張メモリのサポートの暗号化と復号化
アポロ構成にjasypt暗号化と復号化の操作を使用する方法を紹介する前のセクション、基本的なニーズを達成することができますが、いくつかの不十分があります。
jasyptのみの設定変更が発生した場合、起動復号化時にこの設定ENC(XX)フォーマット、と春に更新することはできません。アポロの枠組み自体がこのような構成の暗号化と復号化機能ではありませんので、我々は暗号化と復号化を達成したい、と動的に更新することができれば、あなたはアポロのニーズを満たすために、ソースコードにいくつかの変更を加える必要があります。
再パッケージ化するために必要なソースコードを変更するには、ここで著者は、比較的単純な実装について説明し、クラス名の枠組みの中でアポロのカバーとまったく同じように作成することであるので、彼らはすでに使用中のクライアントを置き換えるものではありません。
ストレージセンタの構成の内容が暗号化されている場合は、アポロクライアントは配送センター構成からプルダウン後の意味は、私たちのような、プロセスを戻って、その後、引き下げ後の構成を復号化するために、それを設定する必要があり、暗号化されています春に結合します。このビジネスのポイントを切断した後、配信センタ暗号化されたコンテンツは、自動的にユーザーに対して透過的、復号された平文に変えることができます。
アポロは、ソースコードを解析することで、私はそれを行うための最も適切なエントリポイントを見つけ、このクラスはcom.ctrip.framework.apollo.internals.DefaultConfigがあり、DefaultConfigが実装クラスCoonfigインタフェースは、初期設定およびアクセスは次のようになりますのDefaultConfigを治療しました。
内部DefaultConfig設定UPDATECONFIGを更新する方法はありますが、この方法で処理された暗号化データを復号化することができます:
private void updateConfig(Properties newConfigProperties, ConfigSourceType sourceType) {
Set<Object> keys = newConfigProperties.keySet();
for (Object k : keys) {
String key = k.toString();
String value = newConfigProperties.getProperty(key);
// 加密Value
if (value.startsWith("ENC(") && value.endsWith(")")) {
logger.debug("加密Value {}", value);
// 解密然后重新赋值
try {
String decryptValue = AesEncryptUtils.aesDecrypt(value.substring(3, value.length()-1), DECRYPT_KEY);
newConfigProperties.setProperty(key, decryptValue);
} catch (Exception e) {
logger.error("加密配置解密失败", e);
}
}
}
m_configProperties.set(newConfigProperties);
m_sourceType = sourceType;
}
ここで、このフォーマットは、この暗号化された設定内容で識別するために使用され、ENC(XX)形式として、同じ暗号化アルゴリズムを使用して暗号化する必要も割当ての中心となる暗号化コンテンツを復号するためにAESを使用します。復号された平文コンテンツを復号化した後、他のプロセスは変わらず、プロパティに再割り当て。
テストクラスの暗号化、暗号化の設定内容を作成し、アポロに格納されたコピー
public class Test {
public static void main(String[] args) {
String msg = "hello yinjihaun";
try {
String encryptMsg = AesEncryptUtils.aesEncrypt(msg, "1111222233334444");
System.out.println(encryptMsg);
} catch (Exception e) {
e.printStackTrace();
}
}
}
出力は次のよう:
Ke4LIPGOp3jCwbIHtmhmBA ==
次のようにアポロは、暗号化されたコンテンツENCラップを格納する必要があります。
test.input = ENC(Ke4LIPGOp3jCwbIHtmhmBA ==)
モード又は試験前のコードと、およびスプリング構成Asを取得正常復号されたデータを得るために注入することができ、そして中心を設定した後、クライアントにリアルタイムで変更することができるうまく解読を押し込みます。
この記事は、に抜粋された「春の雲の戦闘と高度なマイクロ・サービス」の本。