Java 加密密钥和加密字符串的解密
因此,我认为我已经很好地加密了我的密钥和字符串,但解密正成为我的问题。下面是我的代码:Java 加密密钥和加密字符串的解密,java,security,encryption,cryptography,Java,Security,Encryption,Cryptography,因此,我认为我已经很好地加密了我的密钥和字符串,但解密正成为我的问题。下面是我的代码: package ReadFileExample; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java
package ReadFileExample;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.KeyStore;
public class generatekey {
static Cipher cipher;
public static void main(String[] args) throws Exception {
// generating a symmetric key using the AES algorithm
KeyGenerator generator = KeyGenerator.getInstance("AES");
// 128 bit key
generator.init(256);
//generates a secret key
SecretKey secretkey = generator.generateKey();
// returns an AES cipher
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
//print key
System.out.println("Key: " + cipher);
String plainText = "Hello World";
// call to method encrypt
String hexEncryptedByteText = encrypt(plainText, secretkey);
// print orignial text and encrypted text
System.out.println("Plain Text: " + plainText);
System.out.println("Encrypted Text: " + hexEncryptedByteText);
int plainTextlength = plainText.length();
System.out.println("length of text: " + plainTextlength);
// allows to write data to a file
FileOutputStream fos = null;
// write bytes to file
BufferedOutputStream bos = null;
// create file to which data needs to be written
String fileName = "C:/Users/******/newFile.txt";
try{
// allows written data to go into the written path
fos = new FileOutputStream(fileName);
// converts written data into bytes
bos = new BufferedOutputStream(fos);
// writes the encrypted text into file
bos.write(hexEncryptedByteText.length());
System.out.println("encryptedText has been written successfully in "
+fileName);
// allows to catch bug in code
} catch (IOException e) {
e.printStackTrace();
} finally {
try{
// check for null exception
if (bos != null){
bos.close();
}
// check for null exception
if (fos != null){
fos.close();
}
} catch (IOException e){
e.printStackTrace();
}
}
// creates a file input stream by opening a path to the file needed
FileInputStream fin = new FileInputStream("C:/Users/*****/public.cert");
// implements the X509 certificate type
CertificateFactory f = CertificateFactory.getInstance("X.509");
// initalizes data found in the file
X509Certificate certificate = (X509Certificate)f.generateCertificate(fin);
// gets public key from this certificate
PublicKey pk = certificate.getPublicKey();
System.out.println(pk);
String hexEncryptedByteKey = encryptedKey(pk, secretkey);
System.out.println("Encrypted Key: " + hexEncryptedByteKey);
System.out.println("Encrypted Key length: " + hexEncryptedByteKey.length());
// allows to write data to a file
FileOutputStream newFos = null;
// write bytes to file
BufferedOutputStream newBos = null;
// create file to which data needs to be written
String fileNameKey = "C:/Users/****/symmetric.txt";
try{
// allows written data to go into the written path
newFos = new FileOutputStream(fileNameKey);
// converts written data into bytes
newBos = new BufferedOutputStream(newFos);
// writes the encrypted text into file
newBos.write(hexEncryptedByteKey.length());
System.out.println("encryptedKey has been written successfully in "
+fileNameKey);
// allows to catch bug in code
} catch (IOException e) {
e.printStackTrace();
} finally {
try{
// check for null exception
if (newBos != null){
newBos.close();
}
// check for null exception
if (newFos != null){
newFos.close();
}
} catch (IOException e){
e.printStackTrace();
}
}
// load keystore to get private key
KeyStore ks = KeyStore.getInstance("JKS");
String password = "*****";
char[] passwordChar = password.toCharArray();
System.out.println("password: " + passwordChar);
// locate file
try (FileInputStream fis = new FileInputStream("C:/Users/*****/keystore.jks")) {
ks.load(fis, passwordChar);
}
// protect password for keystore
KeyStore.ProtectionParameter protParam = new KeyStore.PasswordProtection(passwordChar);
// get private key from keystore
KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry)
ks.getEntry("*****", protParam);
PrivateKey myPrivateKey = pkEntry.getPrivateKey();
System.out.println("private key: " + myPrivateKey);
//method declaration
String decryptedKey = decryptedKey(myPrivateKey, hexEncryptedByteKey);
System.out.println("decrypted Key: " + decryptedKey);
String hexDecryptedByteText = decryptedTextHex(decryptedKey, hexEncryptedByteText);
System.out.println("key: " + hexDecryptedByteText);
}
public static String encrypt(String plainText, SecretKey secretkey) throws Exception {
//Encodes the string into a sequence of bytes
byte[] plainTextByte = plainText.getBytes();
//intialize cipher to encryption mode
cipher.init(Cipher.ENCRYPT_MODE, secretkey);
//data is encrypted
byte[] encryptedByte = cipher.doFinal(plainTextByte);
//Base64.Encoder encoder = Base64.getEncoder();
//encodes bytes into a string using Base64
byte[] encryptedByteText = Base64.getEncoder().encode(plainTextByte);
String hexEncryptedByteText = DatatypeConverter.printHexBinary(plainTextByte);
// return the string encrypted text to the main method
return hexEncryptedByteText;
}
public static String encryptedKey(PublicKey pk, SecretKey secretkey) throws Exception {
// data written to byte array
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// writes data types to the output stream
ObjectOutputStream writter = new ObjectOutputStream(baos);
//specific object of secretkey is written to the output stream
writter.writeObject(secretkey);
//creates a byte array
byte[] plainTextByteKey = baos.toByteArray();
//creates a cipher using the RSA algorithm
Cipher cipher = Cipher.getInstance("RSA");
// initalizes cipher for encryption using the public key
cipher.init(Cipher.ENCRYPT_MODE, pk);
//encrypts data
//byte[] encryptedByteKey = Base64.getEncoder().encode(plainTextByteKey);
String hexEncryptedByteKey = DatatypeConverter.printHexBinary(plainTextByteKey);
//Base64.Encoder encoderKey = Base64.getEncoder();
// encodes the byte array into a string.
//String encryptedTextKey = new String(encryptedByteKey);
return hexEncryptedByteKey;
}
private static String decryptedKey(PrivateKey myPrivateKey, String hexEncryptedByteKey) throws Exception {
//ByteArrayOutputStream baosDecrypt = new ByteArrayOutputStream();
//ObjectOutputStream writterDecrypt = new ObjectOutputStream(baosDecrypt);
//writterDecrypt.writeObject(hexEncryptedByteKey);
//byte[] byteKeyDecrypt = baosDecrypt.toByteArray();
Cipher cipher;
cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, myPrivateKey);
//cipher.doFinal();
//byte [] decryptedKey = Base64.getDecoder().decode(byteKeyDecrypt);
//String decryptedTextKey = new String(byteKeyDecrypt);
byte[] decodedHex = DatatypeConverter.parseHexBinary(hexEncryptedByteKey);
System.out.println("decoded hex key: " + decodedHex);
String decryptedKey = new String(decodedHex, "UTF-8");
return decryptedKey;
}
private static String decryptedTextHex(String decryptedKey, String hexEncryptedByteText) throws Exception {
byte[] decryptedTextByte = decryptedKey.getBytes();
byte[] textString = hexEncryptedByteText.getBytes();
SecretKey key = new SecretKeySpec(decryptedTextByte, 0, decryptedTextByte.length, "AES");
Cipher cipher;
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
//IvParameterSpec iv = new IvParameterSpec(cipher.getIV());
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] decodedTextHex = cipher.doFinal(textString);
byte[] decoded = Base64.getDecoder().decode(decodedTextHex);
String hexDecryptedByteText = DatatypeConverter.printHexBinary(decoded);
return hexDecryptedByteText;
}
}
这就是我得到的错误:
Exception in thread "main" java.security.InvalidKeyException: Parameters missing
at com.sun.crypto.provider.CipherCore.init(CipherCore.java:469)
at com.sun.crypto.provider.AESCipher.engineInit(AESCipher.java:313)
at javax.crypto.Cipher.implInit(Cipher.java:802)
at javax.crypto.Cipher.chooseProvider(Cipher.java:864)
at javax.crypto.Cipher.init(Cipher.java:1249)
at javax.crypto.Cipher.init(Cipher.java:1186)
at ReadFileExample.generatekey.decryptedTextHex(generatekey.java:289)
at ReadFileExample.generatekey.main(generatekey.java:202)
我不确定出了什么问题。如果我对密钥的解密错误,或者只是对字符串的解密。然而,当涉及到密钥的解密时,我没有收到任何错误
更多信息:我生成了一个密钥,用该密钥加密了一个字符串,然后用生成的公钥加密了该密钥。然后我用私钥解密了密钥,最后我需要用解密后的密钥解密字符串
非常感谢您的帮助。我已经为此工作了这么长时间,我真的不知道该怎么办了。]
编辑:另一个问题与我的问题无关。我甚至没有相同的错误消息,我已经下载了解决方案中所述的JCE 您必须小心密钥大小,AES是一种128位的分组密码,支持128、192和256位的密钥,因此如果您的密钥大小不同,则会出现异常,如果密钥大小大于128,则除非您有无限的策略文件,否则代码将无法工作。基本上,这里有很多细节。如果您想查看一些工作代码,请查看此链接:您必须小心密钥大小,AES是一种128位的分组密码,支持128、192和256位密钥,因此如果您的密钥大小有任何不同,您将得到异常,如果密钥大小大于128,则除非您有无限的策略文件,否则代码将无法工作。基本上,这里有很多细节。如果您想看到一些工作代码,请查看此链接:可能重复的工作密钥(DEK)实际上并不加密工作密钥,仅以任何有能力的对手都可以在几秒钟内破解的方式对其进行编码;而且解码错误(在两个级别!),因此解密数据将失败。另外,您的文件写入错误,但您无论如何都不会使用这些文件。但例外情况是,您使用了CBC模式,该模式要求在加密过程中使用相同的初始化向量(IV)也用于解密,方法是在第三个参数中将其传递给
Cipher。init
查看可能的副本,您实际上没有加密工作密钥(DEK)仅以任何有能力的对手都能在几秒钟内突破的方式对其进行编码;而且解码错误(在两个级别!),因此解密数据将失败。另外,您的文件写入错误,但您无论如何都不会使用这些文件。但例外情况是,您使用了CBC模式,该模式要求加密过程中使用的相同初始化向量(IV)也可用于解密,方法是在第三个参数中将其传递给Cipher.init
请参见OP usedKeyGenerator
,以获得AES with。init(256)
这几乎是他们唯一做对的事情。OP使用KeyGenerator
对AES使用.init(256)
这几乎是他们唯一做对的事情。