2016-07-31 60 views
0

掙扎無數小時後,我終於有當前工作的代碼來生成CMS籠罩(RSA-OAEP/PKCS#1)使用JCE/JCA收件人信息數據:如何使用BouncyCastle的lightwigth API生成CMS封裝數據

String digest = "SHA-256"; 
String mgfDigest = "SHA-256"; 

// Data to encrypt 
CMSTypedData msg = new CMSProcessableByteArray(data); 

// Generator for my CMS enveloped data 
CMSEnvelopedDataGenerator envelopedDataGen = new CMSEnvelopedDataGenerator(); 

// Recipient Info Stuff 
JcaAlgorithmParametersConverter paramsConverter = new JcaAlgorithmParametersConverter(); 
OAEPParameterSpec oaepSpec = new OAEPParameterSpec(digest, "MGF1", new MGF1ParameterSpec(mgfDigest), PSource.PSpecified.DEFAULT); 
AlgorithmIdentifier oaepAlgId = paramsConverter.getAlgorithmIdentifier(PKCSObjectIdentifiers.id_RSAES_OAEP, oaepSpec); 
envelopedDataGen.addRecipientInfoGenerator(
     new JceKeyTransRecipientInfoGenerator(
       getCert(), 
       oaepAlgId).setProvider("BC")); 

/* 
    * Generate CMS-Data 
    * CMSOutputEncryptor is my own Class implementing OutputEncryptor 
    */ 
CMSEnvelopedData ed = envelopedDataGen.generate(
     msg, 
     new CMSOutputEncryptor()); 

byte[] encoded = ed.getEncoded(); 

這可以按預期工作,但由於它使用JCE,我的客戶需要安裝無限強度api才能使用此代碼。我寧願一種方法來克服這些需求,因爲我的大多數客戶的手指是拇指...

也許有人可以告訴我一段代碼,它使用純粹的BouncyCastle方式做同樣的事情,以便一個人不需要安裝無限強度api?

回答

0

請注意,我不確定這是否合法在所有國家/所有客戶。

如果你想刪除限制,你可以使用一些反射魔法。這就是我要做的事在我的框架(部分摘自:https://github.com/jruby/jruby/blob/0c345e1b186bd457ebd96143c0816abe93b18fdf/core/src/main/java/org/jruby/util/SecurityHelper.java):限制

import java.lang.reflect.Field; 
import java.lang.reflect.Modifier; 
import java.security.NoSuchAlgorithmException; 
import javax.crypto.Cipher; 

public class UnlimitedStrengthHelper { 

    public static void removeCryptoStrengthRestriction() { 
     try { 
      if (Cipher.getMaxAllowedKeyLength("AES") < 256) { 
       Class jceSecurity = Class.forName("javax.crypto.JceSecurity"); 
       Field isRestricted = jceSecurity.getDeclaredField("isRestricted"); 
       if (Modifier.isFinal(isRestricted.getModifiers())) { 
        Field modifiers = Field.class.getDeclaredField("modifiers"); 
        modifiers.setAccessible(true); 
        modifiers.setInt(isRestricted, isRestricted.getModifiers() & ~Modifier.FINAL); 
        modifiers.setAccessible(false); 
       } 
       isRestricted.setAccessible(true); 
       isRestricted.setBoolean(null, false); 
       isRestricted.setAccessible(false); 
      } 
     } catch (ClassNotFoundException | IllegalAccessException | IllegalArgumentException 
       | NoSuchAlgorithmException | NoSuchFieldException | SecurityException ex) { 
      System.out.println("It is not possible to use unrestricted policy with this JDK, " 
        + "consider reconfiguration: " + ex.getLocalizedMessage()); 
     } 
    } 
} 

代碼首先檢查是否存在(在這種情況下,你不能與AES256工作)。之後,它需要JceSecurity類和它的isRestricted字段。它確保我們可以訪問此字段並最終將其值設置爲false。

順便說一句,謝謝你的CMS例子,它幫了我很多。

+0

感謝這段代碼,但AFAIK這將不再工作,因爲靜態字段終於現在。請查看https://github.com/jruby/jruby/issues/4101。最後,我決定發佈一個完整的java jre,並啓用無限強度api。但很高興知道我的代碼對你有幫助。 –

+0

此行將修改器設置爲非最終: modifiers.setInt(isRestricted,isRestricted.getModifiers()&〜Modifier.FINAL); – Juraj

相關問題