Java 异常:不适当的密钥规范和 DER 长度的短读
Java Exceptions: Inappropriate key specification and short read of DER length
使用 Apache Commons 中的 Base64 函数 API 并使用 DSA 我正在尝试从文件中加载 base 64 编码的 public 密钥,这里是正在使用的方法
/**
* Load a base-64 encoded public key in X.509 format
* @param pkfile the name of the file containing the public key
* @return an instance of PublicKey on success or null on failure
*/
public PublicKey loadBase64PublicKey(String pkfile) {
PublicKey pub;
Base64InputStream bis;
byte[] buffer;
// load the contents of the pkfile into the buffer
try {
bis = new Base64InputStream(new FileInputStream(pkfile));
buffer = new byte[bis.available()];
bis.read(buffer);
bis.close();
} catch (Exception e) {
System.err.println(e.toString());
return null;
}
// use a KeyFactory to parse the data
try {
KeyFactory kf = KeyFactory.getInstance("DSA");
pub = kf.generatePublic(new X509EncodedKeySpec(buffer));
} catch (Exception e) {
e.printStackTrace();
return null;
}
return pub;
}
主要方法:
public static void main(String args[]) {
DigitalSignatureA DSA = new DigitalSignatureA();
// load public key
PublicKey pubKey;
pubKey = DSA.loadBase64PublicKey("sign\pubkey-1.dat");
}
然而,当从 main 调用该方法时,出现以下错误:
java.security.spec.InvalidKeySpecException: Inappropriate key specification: IOException: Short read of DER length
at sun.security.provider.DSAKeyFactory.engineGeneratePublic(Unknown Source)
at java.security.KeyFactory.generatePublic(Unknown Source)
at DigitalSignatureAssignment.loadBase64PublicKey(DigitalSignatureAssignment.java:147)
at DigitalSignatureAssignment.main(DigitalSignatureAssignment.java:224)
第 147 行将是 pub = kf.generatePublic(new X509EncodedKeySpec(buffer));
文件中的 public 密钥以 X509 编码,但以 base64 编码保存,Base64InputStream 解码任何输入。
Java InputStream.available()
is never guaranteed to tell you how much (more) data exists
Note that while some implementations of InputStream will return the total number of bytes in the stream, many will not. It is never correct to use the return value of this method to allocate a buffer intended to hold all data in this stream.
和in this commons-codec case it doesn't even try
Returns:
0 if the InputStream has reached EOF, 1 otherwise
要么选择一个足够大的缓冲区大小作为开始,要么继续扩展它并阅读更多内容直到 EOF,或者两者结合。或者将文件作为文本读入内存(例如 j8+ 中的 Files.readAllLines
或 Files.readAllBytes
),然后解码 in-memory 副本(FWIW j8+ 现在有 java.util.Base64
而你不需要commons-codec为此)
使用 Apache Commons 中的 Base64 函数 API 并使用 DSA 我正在尝试从文件中加载 base 64 编码的 public 密钥,这里是正在使用的方法
/**
* Load a base-64 encoded public key in X.509 format
* @param pkfile the name of the file containing the public key
* @return an instance of PublicKey on success or null on failure
*/
public PublicKey loadBase64PublicKey(String pkfile) {
PublicKey pub;
Base64InputStream bis;
byte[] buffer;
// load the contents of the pkfile into the buffer
try {
bis = new Base64InputStream(new FileInputStream(pkfile));
buffer = new byte[bis.available()];
bis.read(buffer);
bis.close();
} catch (Exception e) {
System.err.println(e.toString());
return null;
}
// use a KeyFactory to parse the data
try {
KeyFactory kf = KeyFactory.getInstance("DSA");
pub = kf.generatePublic(new X509EncodedKeySpec(buffer));
} catch (Exception e) {
e.printStackTrace();
return null;
}
return pub;
}
主要方法:
public static void main(String args[]) {
DigitalSignatureA DSA = new DigitalSignatureA();
// load public key
PublicKey pubKey;
pubKey = DSA.loadBase64PublicKey("sign\pubkey-1.dat");
}
然而,当从 main 调用该方法时,出现以下错误:
java.security.spec.InvalidKeySpecException: Inappropriate key specification: IOException: Short read of DER length
at sun.security.provider.DSAKeyFactory.engineGeneratePublic(Unknown Source)
at java.security.KeyFactory.generatePublic(Unknown Source)
at DigitalSignatureAssignment.loadBase64PublicKey(DigitalSignatureAssignment.java:147)
at DigitalSignatureAssignment.main(DigitalSignatureAssignment.java:224)
第 147 行将是 pub = kf.generatePublic(new X509EncodedKeySpec(buffer));
文件中的 public 密钥以 X509 编码,但以 base64 编码保存,Base64InputStream 解码任何输入。
Java InputStream.available()
is never guaranteed to tell you how much (more) data exists
Note that while some implementations of InputStream will return the total number of bytes in the stream, many will not. It is never correct to use the return value of this method to allocate a buffer intended to hold all data in this stream.
和in this commons-codec case it doesn't even try
Returns:
0 if the InputStream has reached EOF, 1 otherwise
要么选择一个足够大的缓冲区大小作为开始,要么继续扩展它并阅读更多内容直到 EOF,或者两者结合。或者将文件作为文本读入内存(例如 j8+ 中的 Files.readAllLines
或 Files.readAllBytes
),然后解码 in-memory 副本(FWIW j8+ 现在有 java.util.Base64
而你不需要commons-codec为此)