Java中的加密和解密
我想在Java文件中存储加密密码。 我看到了一个使用javax.crypto的解决方案,但问题是密钥 是动态生成的,它是随机的 然后,将在运行时在Java程序中获取并解密此密码。 考虑到我将在一个文件中存储一个已经加密的密码,我想获得 解密时,请输入正确的文本 有没有办法告诉javax.crypto方法:Java中的加密和解密,java,encryption,Java,Encryption,我想在Java文件中存储加密密码。 我看到了一个使用javax.crypto的解决方案,但问题是密钥 是动态生成的,它是随机的 然后,将在运行时在Java程序中获取并解密此密码。 考虑到我将在一个文件中存储一个已经加密的密码,我想获得 解密时,请输入正确的文本 有没有办法告诉javax.crypto方法: key = KeyGenerator.getInstance(algorithm).generateKey() 可以用基于某个私钥生成的我自己的密钥替换吗 有人能告诉我一些如何做到这一点的资
key = KeyGenerator.getInstance(algorithm).generateKey()
可以用基于某个私钥生成的我自己的密钥替换吗
有人能告诉我一些如何做到这一点的资源吗
密钥生成器
用于生成密钥
您可能需要检查KeySpec
、SecretKey
和SecretKeyFactory
类
这是我几个月前做的一个样品 该类对数据进行加密和解密
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;
}
}
下面是一个使用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
对称密钥加密:对称密钥使用相同的密钥进行加密和解密。这种密码学的主要挑战是发送方和接收方之间的密钥交换 示例:以下示例使用对称密钥进行加密和解密算法,该算法是Sun JCE的一部分(JavaCryptographyExtension)。Sun JCE is有两层,加密API层和提供程序层 DES(DataEncryptionSstandard)是一种流行的对称密钥算法。目前DES已经过时,被认为是不安全的三重DES和DES的一个更强变体。它是一种对称密钥分组密码。还有其他算法,如Blowfish、Twofish和AES(A高级E加密S标准)。AES是DES上最新的加密标准 步骤:
密钥生成器和算法生成密钥。我们正在使用desed
李>
编码文本:为了跨平台的一致性,使用UTF-8编码将纯文本编码为字节李>
加密文本:使用加密模式
实例化密码
,使用密钥并加密字节李>
解密文本:使用解密模式
实例化密码
,使用相同的密钥解密字节李>
以上给出的所有步骤和概念都是相同的,我们只是替换算法
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
示例:密码有两种模式,即加密和解密。我们必须在每次设置模式后开始加密或解密文本。
如果使用静态密钥,则加密和解密总是给出相同的结果
public static final String CRYPTOR_KEY = "your static key here";
byte[] keyByte = Base64.getDecoder().decode(CRYPTOR_KEY);
key = new SecretKeySpec(keyByte, "AES");
您可能想使用这个库(Java简化加密),它非常容易使用。(另外,建议检查加密密码,而不是解密加密密码)
要使用jasypt,如果您使用的是maven,可以将jasypt包含到pom.xml文件中,如下所示:
<dependency>
<groupId>org.jasypt</groupId>
<artifactId>jasypt</artifactId>
<version>1.9.3</version>
<scope>compile</scope>
</dependency>
注意:每次调用encryptPassword时,加密密码都是不同的,但checkPassword方法仍然可以检查未加密密码是否与每个加密密码都匹配
要对照加密密码检查未加密密码,可以使用checkPassword方法:
public static boolean checkPassword(String inputPassword, String encryptedStoredPassword) {
StrongPasswordEncryptor encryptor = new StrongPasswordEncryptor();
return encryptor.checkPassword(inputPassword, encryptedStoredPassword);
}
下面的页面提供了创建安全加密密码所涉及的复杂性的详细信息
谢谢你,伙计。你能给我介绍一些如何使用密钥规范的例子吗?这个例子对一些加密函数有很大的帮助,但它会影响太多其他函数。该示例使用字符串
作为键。此外,它静默地使用不安全的ECB模式加密。也没有真实性或完整性控制。(字符)编码/解码正常,默认填充模式也正常。但总的来说,这个代码是不安全的。oneiros还可以看看我的问题。字节[]encryptedText=Base64.decodeBase64((encryptedString);此行出错。字符串无法转换为字节。在晚些时候,为什么要使用apache commons for Base64。Java内置Base64。-1您不能将加密文本保存为字符串,因为它可能包含任何字节值,这些字节值可能不编码,更重要的是,它们可能无法解码为字符串
。因此上述代码有时会失败。您认为呢名称空间?这是Java吗?是的,只是对[SecretKey;]静态的一个添加。
public static String encryptPassword(String inputPassword) {
StrongPasswordEncryptor encryptor = new StrongPasswordEncryptor();
return encryptor.encryptPassword(inputPassword);
}
public static boolean checkPassword(String inputPassword, String encryptedStoredPassword) {
StrongPasswordEncryptor encryptor = new StrongPasswordEncryptor();
return encryptor.checkPassword(inputPassword, encryptedStoredPassword);
}