【问题标题】:Passwords in SSL with Jetty tutorialSSL 中的密码与 Jetty 教程
【发布时间】:2012-01-16 17:36:59
【问题描述】:

在这个tutorial 中,以下值来自哪里?

  • password (OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4)
  • keyPassword (OBF:1u2u1wml1z7s1z7a1wnl1u2g)
  • trustPassword (OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4)

【问题讨论】:

  • 请注意,如果您想以纯文本形式存储密码,则只需输入不带任何前缀的密码。

标签: ssl jetty


【解决方案1】:

有人 (ack_ of the Norn Iron Hacker Scene) 编写了一个 Python 脚本来反转 Jetty 密码混淆。当您需要将密钥库导出到其他程序时很有用。

# Jetty Deobfuscation Tool
from __future__ import print_function
import sys

def deobfuscate_jetty(ciphertext):
    plaintext = ""
    for i in range(0, len(ciphertext), 4):
        t = ciphertext[i:i + 4]
        i0 = int(t, 36)
        i1, i2 = divmod(i0, 256)
        x = (i1 + i2 - 254) >> 1
        plaintext += chr(x)
    return plaintext

if __name__ == '__main__':
    if len(sys.argv) == 2:
        print(deobfuscate_jetty(sys.argv[1]))
    else:
        print("Jetty Deobfuscation Tool v1.0")
        print("%s <string>" % sys.argv[0])
        exit(1)

【讨论】:

  • 非常好。这可以在不依赖 Jetty 可用的情况下进行反混淆。谢谢。
  • 为脚本点赞?
【解决方案2】:

OBF: 为前缀的密码来自Jetty 自己的密码混淆系统。这里有更多文档:http://wiki.eclipse.org/Jetty/Howto/Secure_Passwords

请注意,这是混淆而不是加密。它只是阻止人们快速阅读它:

在某些情况下,例如密钥库密码和摘要式身份验证, 系统必须找回原始密码,这需要 混淆方法。混淆算法的缺点是 它只保护密码不被随意查看。

你也可以把它们写清楚,不会有太大变化。

在这种情况下,passwordkeyPasswordtrustPassword 分别是密钥库的密码、密钥密码(如果与密钥库密码相同则应该是可选的)和信任库的密码密码。这些是您在创建这些密钥库时设置的。

【讨论】:

  • 为什么原始文档记录者很难在原始问题的上述链接中写下来?说真的,这给我带来了无数的麻烦——现在仍然如此!我赞成这个回复,因为有人指出了配置中使用的“OBF”业务的来源,但我仍然不知道这些密码来自哪里。这是我提供的东西吗?我不知道。
  • 可以通过搜索Jetty源代码找出混淆前的密码。前几天我花了一些时间,所以以防万一有人需要它......在这种情况下,开放文本中的密码是:“storepwd”->“OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4”和“keypwd”->“OBF: 1u2u1wml1z7s1z7a1wnl1u2g”。
【解决方案3】:

这也让我有点发疯。这是一个可用于生成各种密码的脚本。该脚本适用于这个特定版本的码头:jetty-hightide-8.1.10.v20130312,但可以通过JETTY_VER 变量进行修改。

jetty-passwd.sh

#!/bin/bash

# url: http://wiki.eclipse.org/Jetty/Howto/Secure_Passwords
# set -x

if [ $# -ne 2 ]; then
  echo -e "\nUSAGE: `basename $0`: <user> <password>\n";
  exit 0;
fi

JETTY_VER=8.1.10.v20130312
JETTY_HOME=/opt/jetty-hightide-$JETTY_VER
java -cp $JETTY_HOME/lib/jetty-util-${JETTY_VER}.jar org.eclipse.jetty.util.security.Password $1 $2

示例运行

% ./jetty-passwd.sh me blah
blah
OBF:1t2x1toq1to41t39
MD5:6f1ed002ab5595859014ebf0951522d9
CRYPT:me/DjMjPzbKG.

【讨论】:

    【解决方案4】:

    以下函数是 Thilo 的 Python function 的 ES6 端口。它可用于对 Node 服务器上的密码进行去混淆处理。

    我还添加了一个我改编自的混淆方法:arthepsy/deobf/jetty.obf.py

    此外,我添加了一些 mocha/chai 测试来运行随机密码验证混淆/去混淆方法是对称的。

    const
      clipText = (str, length) => `${str.slice(0, length)}…`,
      fill = (size, fn) => new Array(size).fill(0).map((_, i) => fn ? fn(i) : i);
    
    /** test.js */
    const main = () => {
      const
        generator = new PasswordGenerator({ symbols: true, length: 16 }),
        passwords = fill(100, () => generator.next());
    
      mocha.setup('bdd');
      chai.should();
    
      describe('Test JettyUtil', () =>
        passwords.forEach(pw => {
          const
            ciphertext = JettyUtil.obfuscate(pw),
            plaintext  = JettyUtil.deobfuscate(ciphertext);
          it(clipText(`${pw} → ${ciphertext}`, 64), () =>
            pw.should.equal(plaintext))
        }));
    
      mocha.run();
    };
    
    /** jetty-util.js */
    const
      OBF_PREFIX = 'OBF:',
      divmod = (m, n) => [ Math.trunc(m / n), m % n ],
      unpack = (str) => str.split('').map(c => c.charCodeAt(0) & 0xFF),
      chunk = (str, size) => str.match(new RegExp(`.{1,${size}}`, 'g'));
    
    class JettyUtil {
      static deobfuscate(ciphertext) {
        return chunk(ciphertext.slice(OBF_PREFIX.length), 4)
          .reduce((plaintext, i0) => {
              const [ i1, i2 ] = divmod(parseInt(i0, 36), 256);
            return plaintext + String.fromCharCode((i1 + i2 - 254) >> 1);
          }, '');
      }
      static obfuscate(plaintext) {
        return unpack(plaintext).reduce((ciphertext, b1, index, bytes) => {
          const b2 = bytes[bytes.length - (index + 1)],
            [ i1, i2 ] = [ 127 + b1 + b2, 127 + b1 - b2 ];
          return ciphertext + (i1 * 256 + i2).toString(36).padStart(4, '0');
        }, OBF_PREFIX);
      }
    }
    // export default JettyUtil;
    
    
    /** password-generator.js */
    const Alphabet = {
      UPPERCASE : 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
      LOWERCASE : 'abcdefghijklmnopqrstuvwxyz',
      NUMBERS   : '0123456789',
      SYMBOLS   : ' !"#$%&\'()*+,-./:;<=>?@[\]^_`{|}~'
    };
    
    class PasswordGenerator {
      constructor(config) {
        this.opts = { ...PasswordGenerator.defaultOptions, ...config };
        this.alphabet = Object.entries(this.opts)
          .map(([k, v]) => v === true ? Alphabet[k.toUpperCase()] : null)
          .filter(v => v != null)
          .join('');
      }
      next() {
        return fill(this.opts.length, () => rando(this.alphabet)).join('');
      }
    }
    
    PasswordGenerator.defaultOptions = {
      uppercase : true,
      lowercase : true,
      numbers   : true,
      symbols   : false,
      length    : 12
    };
    
    // export default PasswordGenerator;
    
    main();
    .as-console-wrapper { top: 0; max-height: 100% !important; }
    <script src="https://randojs.com/2.0.0.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/mocha/7.2.0/mocha.min.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/mocha/7.2.0/mocha.css" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/chai/4.2.0/chai.min.js"></script>
    <div id="mocha"></div>

    这是我的原始回复:

    const divmod = (m, n) => [ ~~(m / n), m % n ];
    
    const deobfuscate = (ciphertext) => {
      if (!ciphertext.startsWith('OBF:')) return null;
      let plaintext = '';
      for (let offset = 4; offset < ciphertext.length; offset += 4) {
        const i0 = parseInt(ciphertext.slice(offset, offset + 4), 36);
        const [ i1, i2 ] = divmod(i0, 256);
        plaintext += String.fromCharCode((i1 + i2 - 254) >> 1);
      }
      return plaintext;
    };
    
    const pwList = [
      'OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4', // storepwd
      'OBF:1u2u1wml1z7s1z7a1wnl1u2g',         // keypwd
    ];
    
    pwList.forEach(pw => console.log(deobfuscate(pw)));

    【讨论】:

      猜你喜欢
      • 2011-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-16
      • 1970-01-01
      • 2015-11-24
      • 2013-06-15
      • 2013-12-20
      相关资源
      最近更新 更多