在程序下运行时,我收到此异常。当我做
byte key_bytes[] = new byte[X];
与X<16
,我得到相同的错误但是
无效的AES密钥长度:X字节
如果我用X>=16
写这个,我会收到我在标题中写的错误。
以下是我得到的异常以及之后的代码
Exception in thread "main" java.security.InvalidKeyException: Invalid AES key length: 444 bytes
at com.sun.crypto.provider.AESCipher.engineGetKeySize(AESCipher.java:495)
at javax.crypto.Cipher.passCryptoPermCheck(Cipher.java:1062)
at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1020)
at javax.crypto.Cipher.init(Cipher.java:1225)
at javax.crypto.Cipher.init(Cipher.java:1166)
at Main.main(Main.java:87)
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import java.nio.ByteBuffer;
import java.security.*;
import java.security.cert.CertificateException;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class Main
{
public static void main(String[] args) throws IOException, UnrecoverableKeyException, KeyStoreException, NoSuchAlgorithmException, NoSuchPaddingException, CertificateException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, SignatureException{
//open the file containing keys
File file = new File("keys/ks_file.jks");
//cipher object that will hold the information
Cipher aes = Cipher.getInstance("AES/ECB/PKCS5Padding");
//create keystore object from stored keys inside the file
KeyStore keystore = loadKeyStore(file, "sergey", "JKS");
//messageDigest instance
MessageDigest md = MessageDigest.getInstance("SHA1");
//singanture instance
Signature dsa = Signature.getInstance("SHA1withDSA");
//params for getting keys
String allias = "enc_key", password = "sergey";
SecureRandom s_random = SecureRandom.getInstance("SHA1PRNG");
//create random bytes for semtric key
byte key_bytes[] = new byte[16];
s_random.setSeed(711);
s_random.nextBytes(key_bytes);
Key key = new SecretKeySpec(key_bytes, "AES");
Key key_enc = keystore.getKey(allias, password.toCharArray());
KeyPair enc_key = null;
if (key_enc instanceof PrivateKey) {
// Get certificate of public key
java.security.cert.Certificate cert = keystore.getCertificate(allias);
// Get public key
PublicKey publicKey = cert.getPublicKey();
enc_key = new KeyPair(publicKey, (PrivateKey) key_enc);
}
//cipher the file
aes.init(Cipher.ENCRYPT_MODE, key);
FileInputStream fis;
FileOutputStream fos;
CipherInputStream cis;
fis = new FileInputStream("tmp/a.txt");
cis = new CipherInputStream(fis, aes);
fos = new FileOutputStream("tmp/b.txt");
byte[] b = new byte[8];
int i = cis.read(b);
byte[] bytes = ByteBuffer.allocate(4).putInt(i).array();
//update message digest for signature
md.update(bytes);
while (i != -1) {
fos.write(b, 0, i);
i = cis.read(b);
bytes = ByteBuffer.allocate(4).putInt(i).array();
md.update(bytes);
}
fis.close();
cis.close();
fos.close();
//encode the secret key
aes.init(Cipher.ENCRYPT_MODE, (Key)enc_key.getPublic());
byte[] cipherKey = aes.doFinal(key.toString().getBytes());
//we save the final digest
byte[] hash = md.digest();
//init singature with private key
dsa.initSign(enc_key.getPrivate());
//update the signature with the hash aster digest
dsa.update(hash);
//final signature
byte[] sig = dsa.sign();
//creating config xml
try {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
// root elements
Document doc = docBuilder.newDocument();
Element rootElement = doc.createElement("config");
doc.appendChild(rootElement);
// signature elements
Element sig_xml = doc.createElement("sig");
rootElement.appendChild(sig_xml);
sig_xml.setAttribute("value", sig.toString());
// key element
Element key_xml = doc.createElement("key");
rootElement.appendChild(key_xml);
key_xml.setAttribute("value", cipherKey.toString());
// write the content into xml file
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File("./config.xml"));
transformer.transform(source, result);
System.out.println("File saved!");
} catch (ParserConfigurationException pce) {
pce.printStackTrace();
} catch (TransformerException tfe) {
tfe.printStackTrace();
}
}
/**
* Reads a Java keystore from a file.
*
* @param keystoreFile
* keystore file to read
* @param password
* password for the keystore file
* @param keyStoreType
* type of keystore, e.g., JKS or PKCS12
* @return the keystore object
* @throws KeyStoreException
* if the type of KeyStore could not be created
* @throws IOException
* if the keystore could not be loaded
* @throws NoSuchAlgorithmException
* if the algorithm used to check the integrity of the keystore
* cannot be found
* @throws CertificateException
* if any of the certificates in the keystore could not be loaded
*/
public static KeyStore loadKeyStore(final File keystoreFile,
final String password, final String keyStoreType)
throws KeyStoreException, IOException, NoSuchAlgorithmException,
CertificateException {
if (null == keystoreFile) {
throw new IllegalArgumentException("Keystore url may not be null");
}
final URI keystoreUri = keystoreFile.toURI();
final URL keystoreUrl = keystoreUri.toURL();
final KeyStore keystore = KeyStore.getInstance(keyStoreType);
InputStream is = null;
try {
is = keystoreUrl.openStream();
keystore.load(is, null == password ? null : password.toCharArray());
} finally {
if (null != is) {
is.close();
}
}
return keystore;
}
}
答案 0 :(得分:-2)
尝试安装Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files
这是无效密钥长度背后的主要问题之一。
可在Oracle http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
上找到下载local_policy
和US_export_policy
并将其放入您的
Java\jdk1.6.0_45\jre\lib\security