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 used
KeyGenerator
,以获得AES with
。init(256)
这几乎是他们唯一做对的事情。OP使用
KeyGenerator
对AES使用
.init(256)
这几乎是他们唯一做对的事情。