【问题标题】:problem reading a publickey file and use the key to encrypt another file读取公钥文件并使用密钥加密另一个文件时出现问题
【发布时间】:2011-05-25 12:15:39
【问题描述】:

我一直在努力阅读一个公钥文件,我想在文件中获取密钥字符串并使用它来加密另一个文件。我正在使用 RSA PKCS1 v1.5 使用 SH1 散列算法对文件进行加密和签名,但这不是问题,问题是我已经获得了要在加密时使用的公钥文件,我似乎无法通过阅读获胜文件并生成一个 publicKey 对象。

代码如下:

void setPublicKey(String file) 
{ 
     try 
     { 
       FileInputStream keyfis = new FileInputStream(file); 
       byte[] encKey = new byte[keyfis.available()]; keyfis.read(encKey);
       keyfis.close();
       X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(encKey);
       KeyFactory keyFactory = KeyFactory.getInstance("RSA");
// I get an exception on the below line
       publicKey = keyFactory.generatePublic(pubKeySpec);
     } catch (Exception e)
       {
         e.printStackTrace();
       }
}

有人可以帮忙吗!

【问题讨论】:

  • 您确定文件末尾没有换行符,对吧?由于您正在将整个文件读入字节数组,因此您需要注意这一点。
  • 如何检查?顺便说一句,我得到的异常是 InvalidKeySpecException : InvalidKeyException :Invalid Key Format.
  • 好吧,鉴于您正在读取整个文件内容作为您的密钥,换行符肯定会搞砸事情。既然已经安全地消除了,你能提供一个堆栈跟踪吗?仅仅知道代码失败并不足以诊断您的问题。
  • 这里是堆栈跟踪:java.security.spec.InvalidKeySpecException:java.security.InvalidKeyException:在 java.security 的 sun.security.rsa.RSAKeyFactory.engineGeneratePublic(Unknown Source) 处的密钥格式无效。 KeyFactory.generatePublic(Unknown Source) at Trunk.Main.setPublicKey(Main.java:422) “这是我设置公钥的地方,如代码片段中所述”,位于 Trunk.Main.Encryption(Main.java:282) Trunk.Main.main(Main.java:92)

标签: java encryption public-key


【解决方案1】:

AFAIK X509 编码密钥是使用 ASN.1 编码的二进制文件。因此,最后关于换行的问题没有任何意义。

如果你有一个文本文件,那么你有一个 PEM 编码文件,我目前不确定在这种情况下你必须使用哪个 KeySpec。

您可以将 PEM 编码密钥转换为 DER 编码密钥(例如使用 OpenSSL),或者您可以使用 BouncyCastle 来支持加载 PEM 编码密钥。

顺便说一句:使用keyfis.read(encKey); 是危险的,因为 read 方法只读取 encKey 字节,但不必这样做。最好从 InputStream 创建一个 DataInputStream 并使用 readFully(encKey):

new DataInputStream(keyfis).readFully(encKey);

【讨论】:

  • 另外,使用available()判断文件长度错误。使用File.length() 确定文件长度。
  • 我仍然得到相同的异常,但现在出现了 IOException: null,这是堆栈跟踪:java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: I OException: null at sun.security。 rsa.RSAKeyFactory.engineGeneratePublic(Unknown Source) at java.security.KeyFactory.generatePublic(Unknown Source) at Trunk.Main.setPublicKey(Main.java:425) at Trunk.Main.Encryption(Main.java:282) 在 Trunk。 Main.main(Main.java:92)
  • 正如我所写,您似乎有一个 PEM 编码的密钥 - 您无法使用 X509EncodedKeySpec 加载 PEM 编码的密钥
【解决方案2】:

找到了解决方案,但还不确定它是否是正确的解决方案,因为我仍然需要获取 PrivateKey 并解密文件,但现在我能够使用提供的 PublicKey 作为模数对其进行加密,但我没有指数,我只是用一些常见的数字“65537”作为指数 我读到它不是加密的关键部分。

我不得不更改逻辑以使用 RSAPublicKeySpec(它使用 BigInteger 和 Base64Decoder)而不是 X509EncodedKeySpec 来设置 KeySpec 并继续使用 KeyFactory 对象生成公钥。 现在这个逻辑需要模数和指数。

byte[] buffer = new byte[(int) new File(file).length()];
BufferedInputStream f = new BufferedInputStream(new FileInputStream(file));
f.read(buffer);
String modulusBase64 = new String(buffer);
BASE64Decoder b64dec = new BASE64Decoder();
String exponentBase64 = "65537";
RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(new BigInteger    (1,                      b64dec.decodeBuffer(modulusBase64)), new BigInteger(1,     b64dec.decodeBuffer(exponentBase64)));
KeyFactory publicKeyFactory = KeyFactory.getInstance("RSA");
publicKey = publicKeyFactory.generatePublic(publicKeySpec);

//这是文件中的PublicKey。 "J45t4SWGbFzeNuunHliNDZcLVeFU7lOpyNkX1xX+sVNaVJK8Cr0rSjUkDC8h9n+Zg7m0MVYk0byafPycmzWNDynpvj2go9mXwmUpmcQprX1vexxT5j1XmAaBZFYaJRcPWSVU92pdNh1Sd3USdFjgH0LQ5B3s8F95xdyc/5I5LDKhRobx6c1gUs/rnJfJjAgynrE4AsNsNem+STaZWjeb4J+f5Egy9xTSEl6UWxCClgCwhXopy10cBlH8CucpP0cyckOCIOloJ7mEMRCIpp6HPpYexVmXXSikTXh7aQ7tSlTMwUziIERc/zRpyj1Nk96Y7V8AorLFrn1R4Of66mpAdQ=="

【讨论】:

    猜你喜欢
    • 2021-02-17
    • 1970-01-01
    • 2017-01-04
    • 1970-01-01
    • 2011-03-30
    • 2014-05-26
    • 2012-04-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多