Spring在属性文件中加密和解密API密钥

Posted

技术标签:

【中文标题】Spring在属性文件中加密和解密API密钥【英文标题】:Spring encrypt and decrypt API key in properties file 【发布时间】:2015-12-29 03:50:22 【问题描述】:

原始问题

我在 Tomcat 中有一个属性文件,在 src/test/resources 中有一个用于测试的属性文件。

目前我有以下设置。我的属性文件加载到我的 XML 文件中 config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- Repository and Service layers -->
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:cache="http://www.springframework.org/schema/cache"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
    http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">

    <!-- ========================= RESOURCE DEFINITIONS ========================= -->

    <context:component-scan base-package="be.omniatravel.service" />
    <context:property-placeholder 
        location="file:$catalina.base/conf/omniatravel.properties"
        ignore-unresolvable="true" />
        

    <tx:annotation-driven />

</beans>

test-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- Repository and Service layers -->
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:cache="http://www.springframework.org/schema/cache"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
    http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">

    <!-- ========================= RESOURCE DEFINITIONS ========================= -->

    <context:component-scan base-package="be.omniatravel.service" />
    <context:property-placeholder 
        location="classpath:omniatravel_test.properties"
        ignore-unresolvable="true" />
        

    <tx:annotation-driven />

</beans>

我可以通过将这些值放在我的 Java 文件中来访问这些值

public class SunnycarsClient extends WebServiceGatewaySupport 

    @Value("$sunnycars.serviceUri")
    private String uri; // provided by the webservice
    
    @Value("$sunnycars.operatingKey")
    private String key; // provide by the webservice
    
    @Value("$sunnycars.passphrase")
    private String passphrase; // provided by the webservice


目前,操作密钥和密码短语作为平面文本存储在这些属性中。我想将它们存储为加密值以最大程度地降低风险,并且仍然能够以我现在的方式访问。

更新 1

所以我现在所做的就是将 config.xml 的内容替换为

<?xml version="1.0" encoding="UTF-8"?>
<!-- Repository and Service layers -->
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:cache="http://www.springframework.org/schema/cache"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
    http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">

    <!-- ========================= RESOURCE DEFINITIONS ========================= -->

    <context:component-scan base-package="be.omniatravel.service" />

    <!-- bean definitions -->

    <bean
        class="org.jasypt.spring.properties.EncryptablePropertyPlaceholderConfigurer">
        <constructor-arg>
            <bean class="org.jasypt.encryption.pbe.StandardPBEStringEncryptor">
                <property name="config">
                    <bean class="org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig">
                        <property name="algorithm" value="PBEWithMD5AndDES" />
                        <property name="passwordEnvName" value="APP_ENCRYPTION_PASSWORD" />
                    </bean>
                </property>
            </bean>
        </constructor-arg>
        <property name="locations">
            <list>
                <value>file:$catalina.base/conf/omniatravel.properties</value>
            </list>
        </property>
    </bean>

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="sunnycarsMarshallerUri">
            <value>$sunnycars.marshallerUri</value>
        </property>
        <property name="sunnycarsServiceUri">
            <value>$sunnycars.serviceUri</value>
        </property>
        <property name="sunnycarsContextPath">
            <value>$sunnycars.contextPath</value>
        </property>
        <property name="sunnycarsOperatingKey">
            <value>$sunnycars.operatingKey</value>
        </property>
        <property name="sunnycarsPassphrase">
            <value>$sunnycars.passphrase</value>
        </property>
    </bean>

    <tx:annotation-driven />

</beans>

但我仍然不清楚我应该如何从我的 Java 代码中访问这些。

此外,在属性文件中,我应该将 sunnycars.operatingKey = THE_KEY 替换为 sunnycars.operatingKey = enc(ENCRYPTED_KEY),但是如何获得 ENCRYPTED_KEY 值?

【问题讨论】:

参考this和this 【参考方案1】:

首先你必须从http://www.jasypt.org/下载jasypt1.9* 工具包

和 尝试在cmd 中使用以下命令运行encrypt.dat 文件,例如

encrypt.date input=[YOUR PROPERTY FILE VALUE] password=[加密密钥值] 它会产生 您需要在属性文件中替换的加密值的输出 与

=ENC(输出加密值)

 .. 

        <bean class="org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig">
                  <property name="algorithm" value="PBEWithMD5AndDES" />
                  <property name="password" value="APP_ENCRYPTION_PASSWORD" />
       </bean> ..

您还可以在类文件中硬编码密码并分配给 bean

<bean class="org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig">
                  <property name="algorithm" value="PBEWithMD5AndDES" />
                  <property name="password" value="#Key.keyValue" />
       </bean> 

其中 Key.keyValue 是 Key 类的静态方法。

【讨论】:

这对我有用。我有 2 个问题使我的代码无法工作 1. 我使用 【参考方案2】:

看看Jasypt。它支持加密属性 (http://www.jasypt.org/spring31.html)。

【讨论】:

您的问题存在一个how to。

以上是关于Spring在属性文件中加密和解密API密钥的主要内容,如果未能解决你的问题,请参考以下文章

Spring Cloud教程加密和解密

Spring Cloud(03)——内置加解密支持

springcloud-加密和解密

没有Jasypt Spring的加密和解密属性文件

Spring Cloud Config 加密和解密

国密SM4算法加密解密实现以及与Spring Security集成实现