Java “弹跳城堡”;编码密钥规范未被识别“;

Java “弹跳城堡”;编码密钥规范未被识别“;,java,encryption,amazon-web-services,bouncycastle,public-key-encryption,Java,Encryption,Amazon Web Services,Bouncycastle,Public Key Encryption,在AmazonLinux中运行jar之后,我遇到了这个特殊的错误。它在我的OsX中工作得很好。我在两台机器中使用相同的公钥和私钥。唯一的区别是java版本 我制作、测试和编译脚本的机器: Java(TM)SE运行时环境(build 1.6.0_65-b14-462-11M4609) 亚马逊服务器: OpenJDK运行时环境(amzn-2.4.7.1.40.amzn1-x86_64 u55-b13) 这是导致错误的脚本部分: public PublicKey getPublicKey(String

在AmazonLinux中运行jar之后,我遇到了这个特殊的错误。它在我的OsX中工作得很好。我在两台机器中使用相同的公钥和私钥。唯一的区别是java版本

我制作、测试和编译脚本的机器:

Java(TM)SE运行时环境(build 1.6.0_65-b14-462-11M4609)

亚马逊服务器:

OpenJDK运行时环境(amzn-2.4.7.1.40.amzn1-x86_64 u55-b13)

这是导致错误的脚本部分:

public PublicKey getPublicKey(String _file)
    throws
        NoSuchAlgorithmException,
        NoSuchProviderException,
        InvalidKeySpecException,
        IOException
{
    X509EncodedKeySpec _spec = new X509EncodedKeySpec(_getFileContents(_file));
    KeyFactory _keyFactory = KeyFactory.getInstance(this._keyFactoryAlgo, this._provider);

    this._publicKey = _keyFactory.generatePublic(_spec);

    return this._publicKey;
}
GetFileContents:

private byte[] _getFileContents(String _fileName) throws IOException
{

    File _file = new File(_fileName);
    FileInputStream _fileStream = new FileInputStream(_file);

    byte[] _contents = new byte[(int) _file.length()];

    _fileStream.read(_contents);

    if(_fileStream != null)
    {
        _fileStream.close();
        _fileStream = null;
    }

    return _contents;
}
以下是完整的错误消息:

java.security.spec.InvalidKeySpecException: encoded key spec not recognised
at org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi.engineGeneratePublic(Unknown Source)
at org.bouncycastle.jcajce.provider.asymmetric.rsa.KeyFactorySpi.engineGeneratePublic(Unknown Source)
at java.security.KeyFactory.generatePublic(KeyFactory.java:328)
at xxx.CryptKey.getPublicKey(CryptKey.java:167)
at xxx.CryptSession.encryptWithPublicKey(CryptSession.java:316)
at xxx.Crypt.encrypt(Crypt.java:57)
at snippet.Snippet.main(Snippet.java:201)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)

您确实在错误地读取文件。您正在忽略
InputStream.read()
的返回值。您应该在循环中调用此方法,因为单个调用不能保证读取整个字节数组

您可以手动阅读:

int offset = 0;
int read =  _fileStream.read(_contents, 0, contents.length);
while (read > 0) {
    offset += read;
    read = _fileStream.read(_contents, offset , contents.length - offset );

}

或者您可以将底层输入流包装到
DataInputStream
中,然后只使用方法。

可能是因为两个不同的平台有不同的编码?将字符串转换为字节[]时可能会出现问题。我是否可以确认?或者更新一个或另一个?我想你可以使用
Charset.defaultCharset()
来检查编码。我得到了
[*]defaultCharset:UTF-8
这两个
getFileContents()
是如何实现的?这里的许多加密问题实际上是关于I/O和正确读取文件或输入流(im)的。或者我面临着与OP相同的问题。如果我使用KeyPairGenerator生成一个新的私钥,它可以正常工作。但是如果我使用以前生成的密钥(我使用AES/CBC/pkcs7填充并存储在keystore中进行加密。从keystore读取并在签名之前解密),我会得到错误。我检查了密钥字节,它与新生成的密钥字节完全相同。