如何使用Java中的密码加密和解密String(Pc不是移动平台)?

Xpl*_*ive 26 java encryption

我想加密一个字符串然后把它放在一个文件上.也想在我想要的时候解密它.我不需要非常强大的安全性.我只是想让其他人更难获取我的数据.

我尝试了几种方法.这是这些.

Md5加密:

如何在Android中散列字符串?

public static final String md5(final String toEncrypt) {
        try {
            final MessageDigest digest = MessageDigest.getInstance("md5");
            digest.update(toEncrypt.getBytes());
            final byte[] bytes = digest.digest();
            final StringBuilder sb = new StringBuilder();
            for (int i = 0; i < bytes.length; i++) {
                sb.append(String.format("%02X", bytes[i]));
            }
            return sb.toString().toLowerCase();
        } catch (Exception exc) {
            return ""; // Impossibru!
        }
    }
Run Code Online (Sandbox Code Playgroud)

我尝试了这个功能,并能够加密字符串,但我不能解密它的数据.所以这不是解决方案.

DES加密:

在java中加密和解密String

密码短语是自动生成的.密码始终是一样的吗?然后我的安全在哪里.所以这也不是我的解决方案.

AES加密:

如何使用另一个字符串作为密码加密/解密字符串?

我也从这个链接尝试过Aes.这里的密钥也是自动生成的?

还有其他方法吗?

小智 50

package com.example;
import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class StrongAES 
{
    public void run() 
    {
        try 
        {
            String text = "Hello World";
            String key = "Bar12345Bar12345"; // 128 bit key
            // Create key and cipher
            Key aesKey = new SecretKeySpec(key.getBytes(), "AES");
            Cipher cipher = Cipher.getInstance("AES");
            // encrypt the text
            cipher.init(Cipher.ENCRYPT_MODE, aesKey);
            byte[] encrypted = cipher.doFinal(text.getBytes());
            System.err.println(new String(encrypted));
            // decrypt the text
            cipher.init(Cipher.DECRYPT_MODE, aesKey);
            String decrypted = new String(cipher.doFinal(encrypted));
            System.err.println(decrypted);
        }
        catch(Exception e) 
        {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) 
    {
        StrongAES app = new StrongAES();
        app.run();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 请解释您的答案,以便提问者能够理解解决方案. (52认同)
  • **警告** 这绝对不安全。您将密码视为密钥,并使用 ECB 模式来加密明文,该明文使用可能会更改的平台编码。完全缺少异常处理。这是采取最短路径来实现不安全的解决方案。 (3认同)
  • 您将在加密消息中获得一个特殊字符。如果需要,请使用编码来避免。 (2认同)

小智 12

package com.ezeon.util.gen;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import javax.crypto.*;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
/*** Encryption and Decryption of String data; PBE(Password Based Encryption and Decryption)
* @author Vikram
*/
public class CryptoUtil 
{

    Cipher ecipher;
    Cipher dcipher;
    // 8-byte Salt
    byte[] salt = {
        (byte) 0xA9, (byte) 0x9B, (byte) 0xC8, (byte) 0x32,
        (byte) 0x56, (byte) 0x35, (byte) 0xE3, (byte) 0x03
    };
    // Iteration count
    int iterationCount = 19;

    public CryptoUtil() {

    }

    /**
     *
     * @param secretKey Key used to encrypt data
     * @param plainText Text input to be encrypted
     * @return Returns encrypted text
     * @throws java.security.NoSuchAlgorithmException
     * @throws java.security.spec.InvalidKeySpecException
     * @throws javax.crypto.NoSuchPaddingException
     * @throws java.security.InvalidKeyException
     * @throws java.security.InvalidAlgorithmParameterException
     * @throws java.io.UnsupportedEncodingException
     * @throws javax.crypto.IllegalBlockSizeException
     * @throws javax.crypto.BadPaddingException
     *
     */
    public String encrypt(String secretKey, String plainText)
            throws NoSuchAlgorithmException,
            InvalidKeySpecException,
            NoSuchPaddingException,
            InvalidKeyException,
            InvalidAlgorithmParameterException,
            UnsupportedEncodingException,
            IllegalBlockSizeException,
            BadPaddingException {
        //Key generation for enc and desc
        KeySpec keySpec = new PBEKeySpec(secretKey.toCharArray(), salt, iterationCount);
        SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec);
        // Prepare the parameter to the ciphers
        AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);

        //Enc process
        ecipher = Cipher.getInstance(key.getAlgorithm());
        ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
        String charSet = "UTF-8";
        byte[] in = plainText.getBytes(charSet);
        byte[] out = ecipher.doFinal(in);
        String encStr = new String(Base64.getEncoder().encode(out));
        return encStr;
    }

    /**
     * @param secretKey Key used to decrypt data
     * @param encryptedText encrypted text input to decrypt
     * @return Returns plain text after decryption
     * @throws java.security.NoSuchAlgorithmException
     * @throws java.security.spec.InvalidKeySpecException
     * @throws javax.crypto.NoSuchPaddingException
     * @throws java.security.InvalidKeyException
     * @throws java.security.InvalidAlgorithmParameterException
     * @throws java.io.UnsupportedEncodingException
     * @throws javax.crypto.IllegalBlockSizeException
     * @throws javax.crypto.BadPaddingException
     */
    public String decrypt(String secretKey, String encryptedText)
            throws NoSuchAlgorithmException,
            InvalidKeySpecException,
            NoSuchPaddingException,
            InvalidKeyException,
            InvalidAlgorithmParameterException,
            UnsupportedEncodingException,
            IllegalBlockSizeException,
            BadPaddingException,
            IOException {
        //Key generation for enc and desc
        KeySpec keySpec = new PBEKeySpec(secretKey.toCharArray(), salt, iterationCount);
        SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec);
        // Prepare the parameter to the ciphers
        AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);
        //Decryption process; same key will be used for decr
        dcipher = Cipher.getInstance(key.getAlgorithm());
        dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
        byte[] enc = Base64.getDecoder().decode(encryptedText);
        byte[] utf8 = dcipher.doFinal(enc);
        String charSet = "UTF-8";
        String plainStr = new String(utf8, charSet);
        return plainStr;
    }    
    public static void main(String[] args) throws Exception {
        CryptoUtil cryptoUtil=new CryptoUtil();
        String key="ezeon8547";   
        String plain="This is an important message";
        String enc=cryptoUtil.encrypt(key, plain);
        System.out.println("Original text: "+plain);
        System.out.println("Encrypted text: "+enc);
        String plainAfter=cryptoUtil.decrypt(key, enc);
        System.out.println("Original text after decryption: "+plainAfter);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • **警告** 不安全的代码!DES 和 MD5。为什么不使用二战密码呢?然后您就可以成功地预防幼儿。实际的异常处理怎么样而不是举手投降呢? (2认同)

Ima*_*ari 7

很好的回答Vignesh,谢谢!

我只想补充一点,如果你想以某种方式将加密的字节数组存储为String然后检索并解密它(通常用于模糊数据库值),你可以使用这种方法:

import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class StrongAES 
{
    public void run() 
    {
        try 
        {
            String text = "Hello World";
            String key = "Bar12345Bar12345"; // 128 bit key
            // Create key and cipher
            Key aesKey = new SecretKeySpec(key.getBytes(), "AES");
            Cipher cipher = Cipher.getInstance("AES");
            // encrypt the text
            cipher.init(Cipher.ENCRYPT_MODE, aesKey);
            byte[] encrypted = cipher.doFinal(text.getBytes());

            StringBuilder sb = new StringBuilder();
            for (byte b: encrypted) {
                sb.append((char)b);
            }

            // the encrypted String
            String enc = sb.toString();
            System.out.println("encrypted:" + enc);

            // now convert the string to byte array
            // for decryption
            byte[] bb = new byte[enc.length()];
            for (int i=0; i<enc.length(); i++) {
                bb[i] = (byte) enc.charAt(i);
            }

            // decrypt the text
            cipher.init(Cipher.DECRYPT_MODE, aesKey);
            String decrypted = new String(cipher.doFinal(bb));
            System.err.println("decrypted:" + decrypted);

        }
        catch(Exception e) 
        {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) 
    {
        StrongAES app = new StrongAES();
        app.run();
    }
}
Run Code Online (Sandbox Code Playgroud)


Sar*_*avu 7

我的要求是将密码以加密形式保存在配置文件中,并在程序运行时解密。为此,我使用了jasypt库 ( jasypt-1.9.3.jar)。这是一个非常好的库,我们只需 4 行代码就可以完成任务。

首先,将 jar 添加到我的项目后,我导入了以下库。

import org.jasypt.util.text.AES256TextEncryptor;
Run Code Online (Sandbox Code Playgroud)

然后我创建了以下方法。然后,我通过传递需要在password参数中加密的文本来调用此方法。使用aesEncryptor.encrypt方法,我加密了存储到变量中的密码myEncryptedPassword

public void EncryptPassword(String password)
{   
    AES256TextEncryptor aesEncryptor = new AES256TextEncryptor();
    aesEncryptor.setPassword("mypassword");
    String myEncryptedPassword = aesEncryptor.encrypt(password);
    System.out.println(myEncryptedPassword );       
}
Run Code Online (Sandbox Code Playgroud)

您可能已经注意到上面代码中使用了methodsetPassword方法和值。mypassword这是为了确保即使他们使用同一库的加密密码,也没有人可以解密密码。

现在我可以看到变量中的值,myEncryptedPassword例如h9oJ4P5P8ToRy38wvK11PUQCBrT1oH/zbMWuMrbOlI0rfZrj+qSg6f/u0jctOs/ZUf9t3shiwnEt05/nq8bnag==. 这是加密后的密码。将此值保留在配置文件中。

然后,我创建了以下方法来解密要在程序中使用的密码。的值passwordFromConfigFile是我从该方法中获得的加密文本EncryptPasswordaesEncryptor.setPassword请注意,您必须在加密密码的方法中使用相同的密码。

public String DecryptPassword(String passwordFromConfigFile)
{           
    AES256TextEncryptor aesEncryptor = new AES256TextEncryptor();
    aesEncryptor.setPassword("mypassword");
    String decryptedPassword = aesEncryptor.decrypt(passwordFromConfigFile);
    return decryptedPassword;   
}
Run Code Online (Sandbox Code Playgroud)

该变量decryptedPassword现在将具有解密的密码值。


小智 5

标记为解决方案的代码对我不起作用。这是我的解决方案。

/*
 * http://www.java2s.com/Code/Java/Security/EncryptingaStringwithDES.htm
 * /sf/ask/1649277311/
 */
package encryptiondemo;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;


/**
 *
 * @author zchumager
 */
public class EncryptionDemo {

  Cipher ecipher;
  Cipher dcipher;

  EncryptionDemo(SecretKey key) throws Exception {
    ecipher = Cipher.getInstance("AES");
    dcipher = Cipher.getInstance("AES");
    ecipher.init(Cipher.ENCRYPT_MODE, key);
    dcipher.init(Cipher.DECRYPT_MODE, key);
  }

  public String encrypt(String str) throws Exception {
    // Encode the string into bytes using utf-8
    byte[] utf8 = str.getBytes("UTF8");

    // Encrypt
    byte[] enc = ecipher.doFinal(utf8);

    // Encode bytes to base64 to get a string
    return new sun.misc.BASE64Encoder().encode(enc);
  }

  public String decrypt(String str) throws Exception {
    // Decode base64 to get bytes
    byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(str);

    byte[] utf8 = dcipher.doFinal(dec);

    // Decode using utf-8
    return new String(utf8, "UTF8");
  }


    public static void main(String args []) throws Exception
    {

        String data = "Don't tell anybody!";
        String k = "Bar12345Bar12345";

        //SecretKey key = KeyGenerator.getInstance("AES").generateKey();
        SecretKey key = new SecretKeySpec(k.getBytes(), "AES");
        EncryptionDemo encrypter = new EncryptionDemo(key);

        System.out.println("Original String: " + data);

        String encrypted = encrypter.encrypt(data);

        System.out.println("Encrypted String: " + encrypted);

        String decrypted = encrypter.decrypt(encrypted);

        System.out.println("Decrypted String: " + decrypted);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 当您必须传输加密数据时,A 认为它比其他解决方案效果更好。代码也简单得多。我只需更改 java.util.Base64 内部类(Java 8)的 sun.misc.BASE64Encoder 和 sun.misc.BASE64Decoder 即可。 (2认同)