当前位置: 首页 > 知识库问答 >
问题:

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

张逸清
2023-03-14

我已经使用openssl生成了一个私钥,并在Terminal/command中执行以下命令:

    null

所有这些都无法解密我的密钥。下面是我根据这篇文章编写的类[https://stackoverflow.com/questions/35276820/decrypting-an-openssl-pem-encoded-rsa-privest-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)
}

我对安全问题一无所知,所以我需要这方面的帮助。提前谢了。

共有1个答案

申屠黎昕
2023-03-14

决定放弃我发布并使用BouncyCastle的方法。这里的示例代码。

对于像我这样的低温描记技术一无所知的人来说容易多了。

 类似资料:
  • 在Java代码中,我应该解密一个加密的单词,如下所示: 我是加密新手,但是我发现了一些如何用Java加密/解密一些AES/CBC的示例。但是它需要盐、密钥和Iv。我发现OpenSsl正在从“密码”中导出这些值,但我没有发现如何Java解密加密值。 有人知道它是怎么工作的吗?盐、钥匙和/或Iv是否存储在加密值中?谢谢你的回答。

  • 主要的问题是,我对C相当陌生,OpenSSL留档对我来说不够清晰,我尝试过使用读和写rsa键到C中的pem文件,但我不太明白。例如,函数如何创建私有和公共?而从何而来?pcszPassphrase的意义是什么? 我会解释,好像这是某种伪代码,这就是我想做的,粗体部分是我不知道如何做的: 生成私钥和公钥作为十六进制缓冲区(客户端) 基本上,我知道如何处理AES加密/解密和通信协议,反正他们已经实现了

  • 本文向大家介绍PHP中使用OpenSSL生成证书及加密解密,包括了PHP中使用OpenSSL生成证书及加密解密的使用技巧和注意事项,需要的朋友参考一下 依赖于OpenSSL扩展 更多关于OpenSS的文章可以查看下面的相关文章

  • 问题内容: 我有一个加密的私钥,并且知道密码。 我需要使用Java库对其进行解密。 不过,我宁愿不要使用BouncyCastle,除非没有其他选择。根据以前的经验,有太多更改,没有足够的文档。 私钥的格式如下: 我相信关键数据是Base64编码的,因为我看到的是64个字符。 我尝试了以下解密密钥: 我得到这个例外 我是否将正确的参数传递给构造函数? 我该如何工作? 我尝试了Ericsonn的建议,

  • 我想使用带有RSA算法的OpenSSL使用私钥加密文件: 现在,如果我执行解密操作: 此操作需要私钥 我知道我应该使用公钥进行加密,如果我使用私钥,我会得到一个签名。 然而,我想这样做是为了学习。

  • 我知道可以使用此链接为OpenSSL中的自签名证书生成一个公钥和一个私钥。但是对于给定的公钥,我有没有可能算出对应的私钥呢?我一直在使用1024位的RSA公钥。