繁体   English   中英

如何从加密密码解密密码

[英]How to decrypt password from encrypted password

当前,我们正在加密用户从登录页面输入的密码,并将其存储在数据库中。 这里正在开发一个新的登录页面以供内部使用,并重复使用相同的用户名和加密密码。 如果用户被授权,则将允许他访问报告。 在这里,我的问题是,我该如何获取他们用来加密的密钥。 想要使用相同的密钥来解密密码,那么我可以继续我的逻辑。

这是我们用来加密密码的代码。

user = userRemote.loginUser(userName, new String(EncryptDecrypt.storePassword(password),"Cp1252"));

Here password is Password entered in the login page.

这是加密密码的方法。

final static byte[] salt = {
        (byte)0xc7, (byte)0x73, (byte)0x21, (byte)0x8c,
        (byte)0x7e, (byte)0xc8, (byte)0xee, (byte)0x99
    };
final static int count = 1;

public static byte[] storePassword(char[] password) throws InternalException {
      PBEKeySpec pbeKeySpec;
      PBEParameterSpec pbeParamSpec;
      SecretKeyFactory keyFac;
      byte[] ciphertext = null;
      try {
        // Install SunJCE provider
        Provider sunJce = new com.sun.crypto.provider.SunJCE();
        Security.addProvider(sunJce);

        // Create PBE parameter set
        pbeParamSpec = new PBEParameterSpec(salt, count);

        pbeKeySpec = new PBEKeySpec(password);
        keyFac = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
        SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec);
        // Create PBE Cipher
        Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");

        // Initialize PBE Cipher with key and parameters
        pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec);

        // Our cleartext
        byte[] cleartext = (new String(password)).getBytes("Cp1252");

        // Encrypt the cleartext
        ciphertext = pbeCipher.doFinal(cleartext);
      } catch (BadPaddingException ex) {
        log.error("EncryptDecrypt: " + ex.getMessage());
        throw new InternalException(ex.getMessage());
      } catch (Exception ex) {
        log.error("EncryptDecrypt: " + ex.getMessage());
        throw new InternalException(ex.getMessage());
      }
     return ciphertext;
  }

这是用于解密密码的类。 在这里,我只有加密的密码作为解密密码的输入。 例如•Ä0?BÒO,因此正在使用它来生成密钥并对其进行解密。 但是,低于例外。 java.security.spec.InvalidKeySpecException:密码不是ASCII

import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;

public class DecryptPassword {

    public static void main(String[] args) {
        String decryptedStr = checkPassword("•Ä0BÒ¦O");
        System.out.println("decryptedStr : "+decryptedStr);
    }

    final static byte[] salt = {
        (byte)0xc7, (byte)0x73, (byte)0x21, (byte)0x8c,
        (byte)0x7e, (byte)0xc8, (byte)0xee, (byte)0x99
    };

    final static int count = 1;

    static String decryptedPassword = "";

     public static String checkPassword(String encryptedPassword) {
          PBEKeySpec pbeKeySpec;
          PBEParameterSpec pbeParamSpec;
          SecretKeyFactory keyFac;
          try {
            // Install SunJCE provider
            Provider sunJce = new com.sun.crypto.provider.SunJCE();
            Security.addProvider(sunJce);
            // Create PBE parameter set
            pbeParamSpec = new PBEParameterSpec(salt, count);
            pbeKeySpec = new PBEKeySpec(encryptedPassword.toCharArray());
            keyFac = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
            SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec);
            // Create PBE Cipher
            Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
            // Initialize PBE Cipher with key and parameters
            pbeCipher.init(Cipher.DECRYPT_MODE, pbeKey, pbeParamSpec);
            byte[] decrypted = pbeCipher.doFinal(encryptedPassword.getBytes());
            decryptedPassword = decrypted.toString();
        } catch (BadPaddingException ex) {
          System.out.println("EncryptDecrypt: " + ex.getMessage());
        } catch (Exception ex) {
          System.out.println("EncryptDecrypt: " + ex.getMessage());
        }
        return decryptedPassword;
      }

}

在这里我应该能够成功解密密码,但是不能解密。有人可以帮助我这里缺少什么吗? 提前致谢。

那不是加密,那是哈希! (轮辋次)

storePassword例程有效地使用密码对其进行加密; 更确切地说, PBEwithMD5andDES使用原始PKCS5v1派生函数从密码派生的密钥(为清楚起见,现在重新命名为PBKDF1),并以MD5,固定盐和1(!)迭代实例化,以原始DES CBC加密密码。 这是以前流行的创建加密哈希的方式的变体。

在1960年代和1970年代,也许是1980年代,在密码学家将注意力转移到设计特定的密码哈希函数之前,使密码成为唯一的密码基元,将密码(密钥排列)转换为密码哈希(非密钥函数)的一种常用方法是将数据用作加密常量的密钥; 对此的微小变化被实现为一个库函数,该库函数不正确地命名为crypt 1970年早期的Unix Unix中用作密码哈希函数,至今仍记忆犹新(有时甚至使用过),但现在经常使用DES-cryptdescrypt来区别于其他方法自此开发了替代产品。

与旨在被解密的密码不同,这是一个散列并且被设计为不可逆。 我不知道有什么方法可以比蛮力更容易地扭转这种方法(即分析性的“断裂”),但是原始的DES,现在通常称为单DES(或1DES),以区别于其直接后继三元DES(或3DES或正式的TDEA)足够脆弱,如果您真的愿意的话,现在可以将其强行使用。 例如, JTR报告单盐解密的速度大约为10M-30M /秒,相当于简单DES的速度约为0.5G /秒,因此在一台计算机上尝试所有DES密钥将花费数年,而在一千台计算机上则需要数天。 ,或者一百万台计算机需要几分钟的时间。 关于hashcat的数据较难找到,但看起来大致可比。 如果您知道如何选择密码,则尝试仅使用可能的密码而不是所有可能的密钥可能会更快。

但是不要。 验证密码哈希正确方法是让用户提供要求的密码,使用相同的参数重复哈希过程(此处很简单,因为它没有像应有的那样使用可变的salt),并查看新的哈希结果是否匹配存储的一个。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM