简体   繁体   English

无法使用 Scala 解密 OpenSSL 生成的私钥

[英]Unable to decrypt OpenSSL generated private key using scala

I have generated a private key using openssl with the following command in terminal/command:我在终端/命令中使用 openssl 和以下命令生成了一个私钥:

openssl genrsa -aes256 -out private_key.pem 2048 openssl genrsa -aes256 -out private_key.pem 2048

Now i am trying to decrypt the key with Scala but i keep getting the following error:现在我试图用 Scala 解密密钥,但我不断收到以下错误:

Exception in thread "main" javax.crypto.BadPaddingException: Given final block not properly padded at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:989) at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:845) at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:446) at javax.crypto.Cipher.doFinal(Cipher.java:2165) at com.kewmann.utilities.security.DecryptRSAKeys.decrypt(DecryptRSAKeys.scala:46) at TestRSAKeyDecrypt$.delayedEndpoint$TestRSAKeyDecrypt$1(TestRSAKeyDecrypt.scala:20) at TestRSAKeyDecrypt$delayedInit$body.apply(TestRSAKeyDecrypt.scala:18) at scala.Function0$class.apply$mcV$sp(Function0.scala:34) at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12) at scala.App$$anonfun$main$1.apply(App.scala:76) at scala.App$$anonfun$main$1.apply(App.scala:76) at scala.collection.immutable.List.foreach(List.scala:381) at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35) at scala.App$class.mai线程“main”中的异常 javax.crypto.BadPaddingException:在 com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:989) 的 com.sun.crypto.provider.CipherCore.doFinal( CipherCore.java:845) 在 com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:446) 在 javax.crypto.Cipher.doFinal(Cipher.java:2165) 在 com.kewmann.utilities.security.DecryptRSAKeys .decrypt(DecryptRSAKeys.scala:46) at TestRSAKeyDecrypt$.delayedEndpoint$TestRSAKeyDecrypt$1(TestRSAKeyDecrypt.scala:20) at TestRSAKeyDecrypt$delayedInit$body.apply(TestRSAKeyDecrypt.scala:18) at scala.Function0$cV$m.apply$ sp(Function0.scala:34) at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12) at scala.App$$anonfun$main$1.apply(App.scala:76) at scala.App $$anonfun$main$1.apply(App.scala:76) at scala.collection.immutable.List.foreach(List.scala:381) at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35) ) 在 scala.App$class.mai n(App.scala:76) at TestRSAKeyDecrypt$.main(TestRSAKeyDecrypt.scala:18) at TestRSAKeyDecrypt.main(TestRSAKeyDecrypt.scala) n(App.scala:76) 在 TestRSAKeyDecrypt$.main(TestRSAKeyDecrypt.scala:18) 在 TestRSAKeyDecrypt.main(TestRSAKeyDecrypt.scala)

I have tried the following:我尝试了以下方法:

  1. Changing various Cipher Algorithm Padding.更改各种密码算法填充。
  2. Changing to Unlimited JCE Policy as I was getting illegal key size error at one point.更改为 Unlimited JCE Policy,因为我曾经收到非法密钥大小错误。
  3. Change various decoders.更换各种解码器。
  4. Converting key to PCKS8 using OpenSSL (this works) but i want to decrypt programatically.使用 OpenSSL 将密钥转换为 PCKS8(这有效)但我想以编程方式解密。

All of which could not decrypt my key.所有这些都无法解密我的密钥。 Below is my class which I wrote base on this post, [https://stackoverflow.com/questions/35276820/decrypting-an-openssl-pem-encoded-rsa-private-key-with-java]:下面是我根据这篇文章写的类,[https://stackoverflow.com/questions/35276820/decrypting-an-openssl-pem-encoded-rsa-private-key-with-java]:

private val random = new SecureRandom()

@throws(classOf[GeneralSecurityException])
def decrypt(keyDataStr: String, ivHex: String, password: String)
{
    val pw = password.getBytes(StandardCharsets.UTF_8)
    val iv = h2b(ivHex)
    val secret = opensslKDF(pw, iv)
    val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
    cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv))
    val keyBytes = Base64.getMimeDecoder.decode(keyDataStr)
    val pkcs1 = cipher.doFinal(keyBytes)
    /* See note for definition of "decodeRSAPrivatePKCS1" */
    val spec = decodeRSAPrivatePKCS1(pkcs1)
    val rsa = KeyFactory.getInstance("RSA")
    rsa.generatePrivate(spec).asInstanceOf[RSAPrivateKeySpec]
}

@throws(classOf[NoSuchAlgorithmException])
private def opensslKDF(pw: Array[Byte], iv: Array[Byte]): SecretKeySpec = {
    val md5 = MessageDigest.getInstance("MD5")
    md5.update(pw)
    md5.update(iv)
    val d0 = md5.digest()
    md5.update(d0)
    md5.update(pw)
    md5.update(iv)
    val d1 = md5.digest()
    val key = new Array[Byte](24)
    System.arraycopy(d0, 0, key, 0, 16)
    System.arraycopy(d1, 0, key, 16, 8)
    new SecretKeySpec(key, "AES")
}

private def h2b(s: CharSequence): Array[Byte] = {
  val len = s.length();
  val b = new Array[Byte](len / 2)
  var src = 0
  var dst = 0
  while ( {
    src < len
  }) {
    val hi = Character.digit(s.charAt({
      src += 1; src - 1
    }), 16)
    val lo = Character.digit(s.charAt({
      src += 1; src - 1
    }), 16)
    b(dst) = (hi << 4 | lo).toByte

    dst += 1
  }
  b
}

def decodeRSAPrivatePKCS1(encoded: Array[Byte]) = {
  val input = ByteBuffer.wrap(encoded)
  if (der(input, 0x30) != input.remaining()) {
    throw new IllegalArgumentException("Excess data")
  }
  if (!BigInteger.ZERO.equals(derint(input))) {
    throw new IllegalArgumentException("Unsupported version")
  }
  val n = derint(input)
  val e = derint(input)
  val d = derint(input)
  val p = derint(input)
  val q = derint(input)
  val ep = derint(input)
  val eq = derint(input)
  val c = derint(input)
  new RSAPrivateCrtKeySpec(n, e, d, p, q, ep, eq, c)
}

private def derint(input: ByteBuffer): BigInteger = {
  val len = der(input, 0x02)
  val value = new Array[Byte](len)
  input.get(value)
  new BigInteger(+1, value)
}

private def der(input: ByteBuffer, exp: Int): Int = {
  val tag = input.get() & 0xFF
  if (tag != exp) {
    throw new IllegalArgumentException("Unexpected tag")
  }
  var n = input.get() & 0xFF
  if (n < 128) {
    n
  }
  else {
    n &= 0x7F
    if ((n < 1) || (n > 2)) {
      throw new IllegalArgumentException("Invalid length")
    }
    var len = 0
    for (i <- 0 to n) {
      len <<= 8
      len |= input.get() & 0xFF
    }
    len
  }
}

def alphanumeric(nrChars: Int = 24): String = {
  new BigInteger(nrChars * 5, random).toString(32)
}

I am totally clueless on security matters so I need some help in this area.我对安全问题一无所知,所以我需要这方面的帮助。 Thanks in advance.提前致谢。

Decided to abandon the approach I posted and used BouncyCastle.决定放弃我发布的方法并使用 BouncyCastle。 Sample code here .示例代码在这里

Much easier for a crytography clueless like me.对于像我这样一无所知的密码学要容易得多。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM