【问题标题】:How to add a datasource with encrypted password in WildFly Swarm with .war packaging?如何在带有 .war 包装的 WildFly Swarm 中添加具有加密密码的数据源?
【发布时间】:2017-10-31 07:25:02
【问题描述】:

我正在使用以下配置将数据源添加到 WildFly 群中的 WAR:

  swarm:
    datasources:
       data-sources:
         MyDS:
           driver-name: oracle
           connection-url: <my-connection-string>
           user-name: <my-user-name>
           password: <my-password-in-clear-text>

如何更改密码以加密而不是明文?

【问题讨论】:

    标签: java datasource wildfly-swarm


    【解决方案1】:

    这是我使用 SecureIdentityLoginModule 的 Oracle12 工作示例:

    swarm:
      datasources:
        data-sources:
          <your-datasoure-name>:
            driver-name: oracle
            connection-url: jdbc:oracle:thin:@<your-oracle-ip>:<your-oracle-port>:<your-oracle-sid>
            security-domain: myEncryptedDs
      security:
        security-domains:
          myEncryptedDs:
            classic-authentication:
              login-modules:
                myLoginModule:
                  code: org.picketbox.datasource.security.SecureIdentityLoginModule
                  flag: required
                  module-options:
                    username: <your-oracle-username>
                    password: <your-encrypted-oracle-password>
    

    使用以下命令可以加密您的密码(这两个 jar 库可以在您创建的 wildfly-swarm-war-File 中找到):

    java -cp <your-path-to-wildfly-jars>\picketbox-4.9.6.Final.jar;<your-path-to-wildfly-jars>\logging-2017.11.0.jar:$CLASSPATH org.picketbox.datasource.security.SecureIdentityLoginModule <your-password>
    

    【讨论】:

      【解决方案2】:

      您需要实现org.wildfly.swarm.spi.api.ConfigurationFilter。 将为文件的每个属性调用您的类。您可以同时更改该值。这是一个如何解密您的值的示例。您必须提供密钥(jvm 启动)来解密您的值。

      public class DecryptPropertyFilter implements ConfigurationFilter {
      
      private EncryptionHelper encryptionHelper;
      
      {
          try {
              encryptionHelper = new EncryptionHelper(System.getProperty("encryption.key"));
          } catch (NoSuchAlgorithmException e) {
              throw new RuntimeException(e);
          }
      }
      
      @Override
      @SuppressWarnings("unchecked")
      public <T> T filter(String key, T value) {
          if (value instanceof String) {
              String str = value.toString();
              if (str.startsWith("ENC(") && str.endsWith(")")) {
                  try {
                      value = (T) encryptionHelper.decrypt(str.substring(4, str.length() - 1));
                  } catch (Exception e) {
                      throw new RuntimeException(e);
                  }
              }
          }
          return value;
      }
      
      }
      

      【讨论】:

        【解决方案3】:

        为了刺尾。

        thorntail:
          datasources:
            data-sources:
              myDS:
                use-java-context: true
                statistics-enabled: true
                driver-name: mysql
                connection-url: ${db.url}
                security-domain: mydbSecure
                jndi-name: java:/myDS
                check-valid-connection-sql: select 1
                valid-connection-checker-class-name: org.jboss.jca.adapters.jdbc.extensions.mysql.MySQLValidConnectionChecker
                validate-on-match: false
                background-validation: true
                background-validation-millis: 10000
                use-fast-fail: true
                min-pool-size: 5
                max-pool-size: 10
                prefill: true
                flush-strategy: FailingConnectionOnly
                exception-sorter-class-name: org.jboss.jca.adapters.jdbc.extensions.mysql.MySQLExceptionSorter
          security:
            security-domains:
              mydbSecure:
                classic-authentication:
                  login-modules:
                    default:
                      module-options:
                        username: ${ds.uname}
                        password: ${ds.pass}
                      flag: required
                      code: org.picketbox.datasource.security.SecureIdentityLoginModule
                cache-type: default
        
        

        这就是密码的编码方式

        public class EncodePassword {
            public static void main(String[] args) throws Exception
            {
                String password = "password";
                String encode = encode(password);
                System.out.println("Encoded password: "+encode);
            }
            private static String encode(String secret) throws NoSuchPaddingException, NoSuchAlgorithmException,
                    InvalidKeyException, BadPaddingException, IllegalBlockSizeException
            {
                byte[] kbytes = "jaas is the way".getBytes();
                SecretKeySpec key = new SecretKeySpec(kbytes, "Blowfish");
                Cipher cipher = Cipher.getInstance("Blowfish");
                cipher.init(Cipher.ENCRYPT_MODE, key);
                byte[] encoding = cipher.doFinal(secret.getBytes());
                BigInteger n = new BigInteger(encoding);
                return n.toString(16);
            }
        }
        

        以下是您将如何解码密码。

        public class DecodePassword {
            public static void main(String[] args) throws Exception {
                String value = "5dfc52b51bd35553df8592078de921bc";
                try {
                    System.out.println(decode(value));
                } catch (Exception io) {
                    io.printStackTrace();
                }
            }
        
            public static char[] decode(String secret)
                    throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
                byte[] kbytes = "jaas is the way".getBytes();
                SecretKeySpec key = new SecretKeySpec(kbytes, "Blowfish");
                BigInteger n = new BigInteger(secret, 16);
                byte[] encoding = n.toByteArray();
                //SECURITY-344: fix leading zeros
                if (encoding.length % 8 != 0) {
                    int length = encoding.length;
                    int newLength = ((length / 8) + 1) * 8;
                    int pad = newLength - length; //number of leading zeros
                    byte[] old = encoding;
                    encoding = new byte[newLength];
                    for (int i = old.length - 1; i >= 0; i--) {
                        encoding[i + pad] = old[i];
                    }
                    //SECURITY-563: handle negative numbers
                    if (n.signum() == -1) {
                        for (int i = 0; i < newLength - length; i++) {
                            encoding[i] = (byte) -1;
                        }
                    }
                }
                Cipher cipher = Cipher.getInstance("Blowfish");
                cipher.init(Cipher.DECRYPT_MODE, key);
                byte[] decode = cipher.doFinal(encoding);
                return new String(decode).toCharArray();
        
            }
        }
        

        了解有关 picketBox 的更多信息。

        https://source.jboss.org/browse/PicketBox/trunk/security-jboss-sx/jbosssx/src/main/java/org/picketbox/datasource/security/SecureIdentityLoginModule.java?r=276

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-02-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多