内存泄漏位于bouncycastle.jce.provider。

huangapple go评论73阅读模式
英文:

Memory leak at bouncycastle.jce.provider

问题

我正在运行一个使用bouncycastle.jce.provider的Java应用程序(openjdk:11.0.8):

group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.65'

我注意到了一个内存泄漏,并且转储显示几乎所有的内存都被javax.crypto.JceSecurity占用了,它是通过java.util.IdentityHashMap实现的。

它看起来是这样的:

内存泄漏位于bouncycastle.jce.provider。

似乎这个HashMap变得越来越大。我在JceSecurity中看到了两个IdentityHashMap,其声明如下:

// 我们已经验证过的提供者的Map<Provider, ?>,value == PROVIDER_VERIFIED是成功验证,value在错误情况下是异常原因
private static final Map<Provider, Object> verificationResults =
        new IdentityHashMap<>();

// 当前正在验证的提供者的Map<Provider, ?>
private static final Map<Provider, Object> verifyingProviders =
        new IdentityHashMap<>();

如何克服这个问题?修复方法可能是什么样的?

以下是该提供者的使用方式,以防它在某种程度上相关:

static {
    Security.addProvider(new BouncyCastleProvider());
}

public static String encrypt(String pkcs8Base64PublicKey, String text) throws InvalidKeySpecException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
    String publicKeyStr = canonizeKey(pkcs8Base64PublicKey);
    PublicKey publicKey = toPublicKey(publicKeyStr);
    Cipher cipher = Cipher.getInstance(DEFAULT_TRANSFORMATION);
    cipher.init(Cipher.ENCRYPT_MODE, publicKey);
    byte[] encryptedText = cipher.doFinal(text.getBytes(Charset.forName("UTF-8")));
    return new String(Base64.getEncoder().encode(encryptedText), Charset.forName("UTF-8"));
}

public static String decrypt(String pkcs8Base64PrivateKey, String encryptedMessage) throws GeneralSecurityException {
    String privateKeyStr = canonizeKey(pkcs8Base64PrivateKey);
    PrivateKey privateKey = toPrivateKey(privateKeyStr);
    Cipher cipher = Cipher.getInstance(DEFAULT_TRANSFORMATION);
    cipher.init(Cipher.DECRYPT_MODE, privateKey);
    byte[] decryptedMessage = Base64.getDecoder().decode(encryptedMessage);
    return new String(cipher.doFinal(decryptedMessage), Charset.forName("UTF-8"));
}
英文:

I'm running a java (openjdk:11.0.8) application using bouncycastle.jce.provider:

group: &#39;org.bouncycastle&#39;, name: &#39;bcprov-jdk15on&#39;, version: &#39;1.65&#39;

I noticed a memory leak and the dump shows that almost all of the memory is comsumed by

javax.crypto.JceSecurity -- &gt; java.util.IdentityHashMap

This is how it looks like:

内存泄漏位于bouncycastle.jce.provider。

It seems that the hashMap gets bigger and bigger. I see 2 IdentityHashMaps in JceSecurity which states:

// Map&lt;Provider,?&gt; of the providers we already have verified
// value == PROVIDER_VERIFIED is successfully verified
// value is failure cause Exception in error case
private static final Map&lt;Provider, Object&gt; verificationResults =
        new IdentityHashMap&lt;&gt;();

// Map&lt;Provider,?&gt; of the providers currently being verified
private static final Map&lt;Provider, Object&gt; verifyingProviders =
        new IdentityHashMap&lt;&gt;();

How can this be overcome? how can a fix look like?

I'm adding below the way this provider is used, in case it is somehow relevant:

static {
    Security.addProvider(new BouncyCastleProvider());
}

public static String encrypt(String pkcs8Base64PublicKey,String text) throws InvalidKeySpecException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
    String publicKeyStr = canonizeKey(pkcs8Base64PublicKey);
    PublicKey publicKey = toPublicKey(publicKeyStr);
    Cipher cipher = Cipher.getInstance(DEFAULT_TRANSFORMATION);
    cipher.init(Cipher.ENCRYPT_MODE, publicKey);
    byte[] encryptedText = cipher.doFinal(text.getBytes(Charset.forName(&quot;UTF-8&quot;)));
    return new String(Base64.getEncoder().encode(encryptedText), Charset.forName(&quot;UTF-8&quot;));
}

public static String decrypt(String pkcs8Base64PrivateKey, String encryptedMessage) throws GeneralSecurityException {
    String privateKeyStr = canonizeKey(pkcs8Base64PrivateKey);
    PrivateKey privateKey = toPrivateKey(privateKeyStr);
    Cipher cipher = Cipher.getInstance(DEFAULT_TRANSFORMATION);
    cipher.init(Cipher.DECRYPT_MODE, privateKey);
    byte[] decryptedMessage = Base64.getDecoder().decode(encryptedMessage);
    return new String(cipher.doFinal(decryptedMessage), Charset.forName(&quot;UTF-8&quot;));
}

答案1

得分: 2

我遇到了相同的问题,我可以用这段小代码来解决。我希望这能帮助到其他人 :)。

private static BouncyCastleProvider bouncycastleprovider = null;

public static synchronized BouncyCastleProvider getinstance () {

    if (bouncycastleprovider == null) {

        bouncycastleprovider = new BouncyCastleProvider();

    }
    return bouncycastleprovider;
}
英文:

I had the same problem, and I could solve it width this small code. I hope this can help somebody 内存泄漏位于bouncycastle.jce.provider。 .

private static BouncyCastleProvider bouncycastleprovider = null;

public static synchronized BouncyCastleProvider getinstance () {

    if (bouncycastleprovider == null) {

        bouncycastleprovider = new BouncyCastleProvider();

    }
    return bouncycastleprovider;
}

huangapple
  • 本文由 发表于 2020年9月16日 05:02:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/63909806.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定