IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    paramiko 解析 AES 加密 key

    Kumu\'s Blog发表于 2013-11-05 00:00:00
    love 0

    对等加密(Reciprocal cipher)又称为对称密钥加密(Symmetric-key algorithm)、对称加密、私钥加密、共享密钥加密,是密码学中的一类加密算法。该类密码的加密算法是它自己本身的逆反函数,所以其解密算法等同于加密算法,也就是说,要还原对等加密的密文,套用加密同样的算法即可得到明文。换句话说,若参数(或密钥)合适的话,两次连续的对等加密运算后会回复原始文字。在数学上,这有时称之为对合。在实际应用中,体现为加密和解密使用同一个密钥,或者知道一方密钥能够轻易计算出另一方密钥。常见的对称加密算法有 DES、3DES、AES、Blowfish、IDEA、RC4、RC5、RC6。

    在说明问题之前,引用维基百科对对称加密的一个说明。今天使用 paramiko 解析 DSA 密钥时出现如下 ERROR:

    ... ...
    paramiko.SSHException: Unknown private key cipher "AES-128-CBC"
    

    DSA 密钥内容如下:

    -----BEGIN DSA PRIVATE KEY-----
    Proc-Type: 4,ENCRYPTED
    DEK-Info: AES-128-CBC,381624AF862F1717C46EF898D9E1FA92
    
    ... ...
    OCGYNLsO68FToi8qJEP1DI9Jvk6tpU3y4ebBqSZnX7jr1M5+Hj5rfMqv7+kp3T4R
    314ae9Ism9AXLIK2miTAcvbexZpbcesadqvo69DMsfhSmKKJYABK3eRYaDlUwkzN
    ... ...
    -----END DSA PRIVATE KEY-----
    

    使用 ssh-keygen -t rsa 测试没有问题,后来得知之前的 DSA 密钥时使用 Secure CRT 生成的,查了相关 AES 算法加密,发现 paramiko 默认并不支持AES算法,所以出现之前的 Unknown Error 错误。后来借助 Google 找到了相关的答案,Unknown private key cipher AES-128-CBC ,顺便记录下。

    解决方法需要修改 paramiko 代码,打开 /usr/lib/pythonX.X/site-packages/paramiko/pkey.py 修改如下:

    ...
    from Crypto.Cipher import DES3, AES
    
    ...
        _CIPHER_TABLE = {
            'AES-128-CBC': { 'cipher': AES, 'keysize': 16, 'blocksize': 16, 'mode': AES.MODE_CBC },
            'DES-EDE3-CBC': { 'cipher': DES3, 'keysize': 24, 'blocksize': 8, 'mode': DES3.MODE_CBC }
        }
    ...
    

    以上修改,保存之后退出即可。

    顺便附带我的 paramiko 测试代码

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    import paramiko
    
    def paramiko_ssh(hostip, cmd):
        ssh = paramiko.SSHClient()
        pkey_file = '/root/.ssh/dsa'
        pkey_pass = '123321'
        ssh_port = 22
        ssh_user = 'root'
        key = paramiko.DSSKey.from_private_key_file(pkey_file, password=pkey_pass) 
        # 如果是 RSA KEY,上一行修改 DSS 为 RSA
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(hostip, ssh_port, ssh_user, pkey=key)
        stdin, stdout, stderr = ssh.exec_command(cmd)
        print stderr.read()
        ssh.close()
    
    if __name__ == "__main__":
        ssh_cmd='touch /tmp/test'
        paramiko_ssh('127.0.0.1', ssh_cmd)
    

    --EOF--



沪ICP备19023445号-2号
友情链接