Java中的加密和解密

时间:2012-04-24 18:22:15

标签: java encryption

我想将加密的密码存储在Java文件中。 我在使用 javax.crypto 的解决方案中看到了,但问题在于关键 是在飞行中生成的,它是随机的。

此密码将在运行时在Java程序中获取和解密。 鉴于我要将已经加密的密码存储在一个文件中 - 我想得到它 解密时的正确文本。

有没有办法告诉javax.crypto方法:

key = KeyGenerator.getInstance(algorithm).generateKey()

是否可以使用基于某些私钥生成的自己的密钥替换它?

有人能指出一些有关如何做到这一点的资源吗?

7 个答案:

答案 0 :(得分:18)

这是一个使用 javax.crypto 库和apache commons编解码器库在Base64中进行编码和解码的解决方案,我正在寻找:

import java.security.spec.KeySpec;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import org.apache.commons.codec.binary.Base64;

public class TrippleDes {

    private static final String UNICODE_FORMAT = "UTF8";
    public static final String DESEDE_ENCRYPTION_SCHEME = "DESede";
    private KeySpec ks;
    private SecretKeyFactory skf;
    private Cipher cipher;
    byte[] arrayBytes;
    private String myEncryptionKey;
    private String myEncryptionScheme;
    SecretKey key;

    public TrippleDes() throws Exception {
        myEncryptionKey = "ThisIsSpartaThisIsSparta";
        myEncryptionScheme = DESEDE_ENCRYPTION_SCHEME;
        arrayBytes = myEncryptionKey.getBytes(UNICODE_FORMAT);
        ks = new DESedeKeySpec(arrayBytes);
        skf = SecretKeyFactory.getInstance(myEncryptionScheme);
        cipher = Cipher.getInstance(myEncryptionScheme);
        key = skf.generateSecret(ks);
    }


    public String encrypt(String unencryptedString) {
        String encryptedString = null;
        try {
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] plainText = unencryptedString.getBytes(UNICODE_FORMAT);
            byte[] encryptedText = cipher.doFinal(plainText);
            encryptedString = new String(Base64.encodeBase64(encryptedText));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return encryptedString;
    }


    public String decrypt(String encryptedString) {
        String decryptedText=null;
        try {
            cipher.init(Cipher.DECRYPT_MODE, key);
            byte[] encryptedText = Base64.decodeBase64(encryptedString);
            byte[] plainText = cipher.doFinal(encryptedText);
            decryptedText= new String(plainText);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return decryptedText;
    }


    public static void main(String args []) throws Exception
    {
        TrippleDes td= new TrippleDes();

        String target="imparator";
        String encrypted=td.encrypt(target);
        String decrypted=td.decrypt(encrypted);

        System.out.println("String To Encrypt: "+ target);
        System.out.println("Encrypted String:" + encrypted);
        System.out.println("Decrypted String:" + decrypted);

    }

}

使用以下输出运行上述程序:

String To Encrypt: imparator
Encrypted String:FdBNaYWfjpWN9eYghMpbRA==
Decrypted String:imparator

答案 1 :(得分:13)

对称密钥密码术:对称密钥使用相同的密钥进行加密和解密。这种类型的密码术的主要挑战是在双方发送者和接收者之间交换密钥。

示例:以下示例使用对称密钥作为Sun JCE的一部分提供的加密和解密算法( J ava C ryptography E xtension)。 Sun JCE有两层,即加密API层和提供者层。

DES D ata E ncryption S 标准)是一种流行的对称密钥算法。目前DES已经过时并被认为是不安全的。 三重DES 以及 DES 的更强变体。它是对称密钥块密码。还有其他算法,如 Blowfish Twofish AES A dvanced E ncryption <强>取值 TANDARD)。 AES是DES的最新加密标准。

步骤:

  1. 添加安全提供程序:我们正在使用JDK提供的SunJCE提供程序。
  2. 生成密钥:使用KeyGenerator和算法生成密钥。我们正在使用DESede
  3. 编码文本:为了跨平台的一致性,使用UTF-8 encoding将纯文本编码为字节。
  4. 加密文字:使用Cipher实例化ENCRYPT_MODE,使用密钥并加密字节。
  5. 解密文字:使用Cipher实例化DECRYPT_MODE,使用相同的密钥并解密字节。
  6. 以上给出的所有步骤和概念都相同,我们只是替换算法。

    import java.util.Base64;    
    import javax.crypto.Cipher;  
    import javax.crypto.KeyGenerator;   
    import javax.crypto.SecretKey;  
    public class EncryptionDecryptionAES {  
        static Cipher cipher;  
    
        public static void main(String[] args) throws Exception {
            /* 
             create key 
             If we need to generate a new key use a KeyGenerator
             If we have existing plaintext key use a SecretKeyFactory
            */ 
            KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
            keyGenerator.init(128); // block size is 128bits
            SecretKey secretKey = keyGenerator.generateKey();
    
            /*
              Cipher Info
              Algorithm : for the encryption of electronic data
              mode of operation : to avoid repeated blocks encrypt to the same values.
              padding: ensuring messages are the proper length necessary for certain ciphers 
              mode/padding are not used with stream cyphers.  
             */
            cipher = Cipher.getInstance("AES"); //SunJCE provider AES algorithm, mode(optional) and padding schema(optional)  
    
            String plainText = "AES Symmetric Encryption Decryption";
            System.out.println("Plain Text Before Encryption: " + plainText);
    
            String encryptedText = encrypt(plainText, secretKey);
            System.out.println("Encrypted Text After Encryption: " + encryptedText);
    
            String decryptedText = decrypt(encryptedText, secretKey);
            System.out.println("Decrypted Text After Decryption: " + decryptedText);
        }
    
        public static String encrypt(String plainText, SecretKey secretKey)
                throws Exception {
            byte[] plainTextByte = plainText.getBytes();
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            byte[] encryptedByte = cipher.doFinal(plainTextByte);
            Base64.Encoder encoder = Base64.getEncoder();
            String encryptedText = encoder.encodeToString(encryptedByte);
            return encryptedText;
        }
    
        public static String decrypt(String encryptedText, SecretKey secretKey)
                throws Exception {
            Base64.Decoder decoder = Base64.getDecoder();
            byte[] encryptedTextByte = decoder.decode(encryptedText);
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            byte[] decryptedByte = cipher.doFinal(encryptedTextByte);
            String decryptedText = new String(decryptedByte);
            return decryptedText;
        }
    }
    

    输出:

    Plain Text Before Encryption: AES Symmetric Encryption Decryption
    Encrypted Text After Encryption: sY6vkQrWRg0fvRzbqSAYxepeBIXg4AySj7Xh3x4vDv8TBTkNiTfca7wW/dxiMMJl
    Decrypted Text After Decryption: AES Symmetric Encryption Decryption
    

    Source

    示例:有两种模式的密码,它们是加密和解密的。我们必须在设置模式后每次启动以加密或解密文本。 enter image description here

答案 2 :(得分:5)

KeyGenerator用于生成

您可能需要查看KeySpecSecretKeySecretKeyFactory

http://docs.oracle.com/javase/1.5.0/docs/api/javax/crypto/spec/package-summary.html

答案 3 :(得分:1)

这是我几个月前制作的一个样本 该类加密和解密数据

import java.security.*;
import java.security.spec.*;

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

public class TestEncryptDecrypt {

private final String ALGO = "DES";
private final String MODE = "ECB";
private final String PADDING = "PKCS5Padding";
private static int mode = 0;

public static void main(String args[]) {
    TestEncryptDecrypt me = new TestEncryptDecrypt();
    if(args.length == 0) mode = 2;
    else mode = Integer.parseInt(args[0]);
    switch (mode) {
    case 0:
        me.encrypt();
        break;
    case 1:
        me.decrypt();
        break;
    default:
        me.encrypt();
        me.decrypt();
    }
}

public void encrypt() {
try {
    System.out.println("Start encryption ...");

    /* Get Input Data */
    String input = getInputData();
    System.out.println("Input data : "+input);

    /* Create Secret Key */
    KeyGenerator keyGen = KeyGenerator.getInstance(ALGO);
    SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
    keyGen.init(56,random);
      Key sharedKey = keyGen.generateKey();

    /* Create the Cipher and init it with the secret key */
    Cipher c = Cipher.getInstance(ALGO+"/"+MODE+"/"+PADDING);
    //System.out.println("\n" + c.getProvider().getInfo());
    c.init(Cipher.ENCRYPT_MODE,sharedKey);
    byte[] ciphertext = c.doFinal(input.getBytes());
    System.out.println("Input Encrypted : "+new String(ciphertext,"UTF8"));

    /* Save key to a file */
    save(sharedKey.getEncoded(),"shared.key");

    /* Save encrypted data to a file */
    save(ciphertext,"encrypted.txt");
} catch (Exception e) {
    e.printStackTrace();
}   
}

public void decrypt() {
try {
    System.out.println("Start decryption ...");

    /* Get encoded shared key from file*/
    byte[] encoded = load("shared.key");
      SecretKeyFactory kf = SecretKeyFactory.getInstance(ALGO);
    KeySpec ks = new DESKeySpec(encoded);
    SecretKey ky = kf.generateSecret(ks);

    /* Get encoded data */
    byte[] ciphertext = load("encrypted.txt");
    System.out.println("Encoded data = " + new String(ciphertext,"UTF8"));

    /* Create a Cipher object and initialize it with the secret key */
    Cipher c = Cipher.getInstance(ALGO+"/"+MODE+"/"+PADDING);
    c.init(Cipher.DECRYPT_MODE,ky);

    /* Update and decrypt */
    byte[] plainText = c.doFinal(ciphertext);
    System.out.println("Plain Text : "+new String(plainText,"UTF8"));
} catch (Exception e) {
    e.printStackTrace();
}   
}

private String getInputData() {
    String id = "owner.id=...";
    String name = "owner.name=...";
    String contact = "owner.contact=...";
    String tel = "owner.tel=...";
    final String rc = System.getProperty("line.separator");
    StringBuffer buf = new StringBuffer();
    buf.append(id);
    buf.append(rc);
    buf.append(name);
    buf.append(rc);
    buf.append(contact);
    buf.append(rc);
    buf.append(tel);
    return buf.toString();
}


private void save(byte[] buf, String file) throws IOException {
      FileOutputStream fos = new FileOutputStream(file);
      fos.write(buf);
      fos.close();
}

private byte[] load(String file) throws FileNotFoundException, IOException {
    FileInputStream fis = new FileInputStream(file);
    byte[] buf = new byte[fis.available()];
    fis.read(buf);
    fis.close();
    return buf;
}
}

答案 4 :(得分:1)

您可能想使用jasypt库(Java简化加密),该库非常易于使用。 (另外,建议您检查加密的密码而不是解密加密的密码)

要使用jasypt,如果您使用的是maven,则可以将jasypt包含在pom.xml文件中,如下所示:

<dependency>
    <groupId>org.jasypt</groupId>
    <artifactId>jasypt</artifactId>
    <version>1.9.3</version>
    <scope>compile</scope>
</dependency>

然后要加密密码,可以使用StrongPasswordEncryptor

public static String encryptPassword(String inputPassword) {
    StrongPasswordEncryptor encryptor = new StrongPasswordEncryptor();
    return encryptor.encryptPassword(inputPassword);
}

注意: 每次调用cryptoPassword时,加密密码都是不同的,但是checkPassword方法仍然可以检查未加密的密码是否仍与每个加密密码匹配。

然后要使用加密密码检查未加密的密码,可以使用checkPassword方法:

public static boolean checkPassword(String inputPassword, String encryptedStoredPassword) {
    StrongPasswordEncryptor encryptor = new StrongPasswordEncryptor();
    return encryptor.checkPassword(inputPassword, encryptedStoredPassword);
}

以下页面提供了有关创建安全加密密码的复杂性的详细信息。

http://www.jasypt.org/howtoencryptuserpasswords.html

答案 5 :(得分:0)

public class GenerateEncryptedPassword {

    public static void main(String[] args){

        Scanner sc= new Scanner(System.in);    
        System.out.println("Please enter the password that needs to be encrypted :");
        String input = sc.next();

        try {
            String encryptedPassword= AESencrp.encrypt(input);
            System.out.println("Encrypted password generated is :"+encryptedPassword);
        } catch (Exception ex) {
            Logger.getLogger(GenerateEncryptedPassword.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

答案 6 :(得分:0)

如果使用静态密钥,则加密和解密总会得到相同的结果;

public static final String CRYPTOR_KEY = "your static key here";
byte[] keyByte = Base64.getDecoder().decode(CRYPTOR_KEY);
key = new SecretKeySpec(keyByte, "AES");