簡體   English   中英

IAIK PKCS#11 包裝器:ECDH 密鑰協議示例

[英]IAIK PKCS#11 Wrapper: ECDH KeyAgreement Example

我嘗試使用 IAIK PKCS#11 包裝器( https://jce.iaik.tugraz.at/sic/Products/Core_Crypto_Toolkits/PKCS_11_Wrapper )執行一些 ECDH 密鑰協議,但不使用 JCE 提供程序。 到目前為止,我沒有找到任何示例,尤其是設置密鑰模板和機制(以及機制參數)。

您是否有一些示例,如何以最佳方式使用 BouncyCastle 執行此操作並驗證結果?

謝謝你!

最后,我讓它自己工作。

首先請注意,IAIK PKCS#11 包裝器不支持 PKCS#11 的所有密鑰派生函數。 DHKeyDerivationParameters.KeyDerivationFunctionType 指定了它支持的內容,遺憾的是,雖然您提供了一個 long,但它會檢查該值是否已知,因此您不能簡單地提供為其他 KDF 函數定義的值。 盡管如此,如果您的 PKCS#11 模塊支持它,您可以使用 DHKeyDerivationParameters.KeyDerivationFunctionType.NULL 並自行進行推導。

對於以下片段,讓 session 是一些 iaik.pkcs.pkcs11.Session,它經過正確驗證以使用選定的 ECDH 密鑰。

執行以下操作以派生密鑰,在這種情況下為 AES(2Des 和 3DES 或其他 AES 長度大致相同):

final long CKA_VALUE_LEN = 0x00000161;

byte[] deriveKey(byte[] publicKey, byte[] salt, long keyDerivationFunction) throws Exception {
    // setting up mechanism:
    EcDH1KeyDerivationParameters params = new EcDH1KeyDerivationParameters(keyDerivationFunction, salt, publicKey);
    Mechanism mechanism = Mechanism.get(PKCS11Constants.CKM_ECDH1_DERIVE );
    mechanism.setParameters(params);

    // setting up keyTemplate, specifying how the derived key looks like:
    Key keyTemplate = new AESSecretKey();
    keyTemplate.putAttribute(CKA_VALUE_LEN, new Long(32));

    AESSecretKey derivedKey = ((AESSecretKey)session.deriveKey(mechanism, key, keyTemplate));
    return derivedKey.getValue().getByteArrayValue();
}

要檢索普通的 ECDH 共享密鑰,請執行以下操作:

byte[] getSharedSecret(byte[] publicKey) throws Exception{
    // setting up mechanism:
    EcDH1KeyDerivationParameters params = new EcDH1KeyDerivationParameters(DHKeyDerivationParameters.KeyDerivationFunctionType.NULL, null, publicKey);
    Mechanism mechanism = Mechanism.get(PKCS11Constants.CKM_ECDH1_DERIVE );
    mechanism.setParameters(params);

    // four our PKCS#11 module, using a GenericSecretKey without length returns
    // the complete derived secret:
    Key keyTemplate = new GenericSecretKey();

    GenericSecretKey derivedKey = ((GenericSecretKey)session.deriveKey(mechanism, key, keyTemplate));
    return derivedKey.getValue().getByteArrayValue();
}

要執行“另一方”並驗證派生值是否符合預期,您可以使用 BouncyCastle 和以下代碼:

void testKeyDerivation(ECPublicKey otherPublic, byte[] salt) throws Exception{
    // create some keypair, which fits to the EC key, IAIK is using:        
    KeyPairGenerator keyGen = KeyPairGenerator.getInstance("ECDH", BouncyCastleProvider.PROVIDER_NAME);
    keyGen.initialize(otherPublic.getParams());
    KeyPair testKeyPair = keyGen.generateKeyPair();
    ECPublicKey publicTestKey = (ECPublicKey) testKeyPair.getPublic();

    // convert the JCE Publickey to the required format, using BouncyCastle:
    byte[] encodedPublicTestKey = EC5Util.convertPoint(publicTestKey.getParams(), publicTestKey.getW(),false).getEncoded(false);
    // format is 0x04 X Y where X and Y are byte[], containing the (padded) coordinates of the point, 
    // specifying the public key    


    // in fact, you need to do only one of these, but I want to show, how both works:
    byte[] iaikDerivedKey =  deriveKey(encodedPublicTestKey, salt, DHKeyDerivationParameters.KeyDerivationFunctionType.SHA1_KDF);
    byte[] iaikDerivedSecret =  getSharedSecret(encodedPublicTestKey);


    // verify that both sides indeed agree:
    KeyAgreement ka = KeyAgreement.getInstance("ECDH", BouncyCastleProvider.PROVIDER_NAME);
    ka.init(testKeyPair.getPrivate());
    ka.doPhase(otherPublic, true);
    byte [] secret = ka.generateSecret();

    Assert.assertTrue(Arrays.equals(iaikDerivedSecret,  secret));

    Digest digest = new SHA1Digest();
    KDF2BytesGenerator kdf = new KDF2BytesGenerator(digest);
    DerivationParameters derivationParameters = new KDFParameters(secret,salt);

    kdf.init(derivationParameters);
    byte[] derivedKey = new byte[iaikDerivedKey.length];
    kdf.generateBytes(derivedKey, 0, iaikDerivedKey.length);
    Assert.assertTrue(Arrays.equals(iaikDerivedKey,  derivedKey));
}

這確實適用於 IAIK PKCS#11 Wrapper Version 1.5 和 BouncyCastle Version 1.59,使用我公司的 PKCS#11 Middleware 和一些智能卡。 我希望它也可以幫助其他人,嘗試做同樣的事情。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM