2016-06-30 8 views
2

thisを参照すると、アルゴリズムAGCM256-KWを使用して暗号化する必要があります。私はJava暗号を使用していますが、そのようなアルゴリズムは見つかりませんでした。私が見つけた最も近いものはAES_256/GCM/NoPaddingでしたが、KW(Key wrapping)はありません。ここCipher.getInstance(String algo)で使用されるJava暗号の「AGCM256-KW」のアルゴリズム文字列は何ですか?

は私のテストコードは、私がJWEためのAPIを持ってjose4jライブラリを使用することができると思うの更新1

public void testEncryption(String algo) { 
    String shared_secret = "[email protected]//x1LwM123QP/ln"; 
    try { 

     // Step 1 - Create SHA-256 digest of the shared key 
     MessageDigest md = MessageDigest.getInstance("SHA-256"); 
     byte[] digest = md.digest(shared_secret.getBytes("UTF-8")); 

     // Step 2 - generate a 256 bit Content Encryption Key(CEK) 
     KeyGenerator kg = KeyGenerator.getInstance("AES"); 
     kg.init(256); 
     SecretKey cek = kg.generateKey(); 

     // Step 3 - encrypt the CEK using 256 bit digest generated in Step 1 
     // and 96 bit random IV. Algorithm should be 

     // random 96 bit Initialize Vector 
     SecureRandom random = new SecureRandom(); 
     // byte iv[] = new byte[96]; 
     // random.nextBytes(iv); 
     byte iv[] = random.generateSeed(96); 
     System.out.println("IV: " + toBase64(iv) + " length: " + iv.length); 
     IvParameterSpec ivspec = new IvParameterSpec(iv); 
     GCMParameterSpec gspec = new GCMParameterSpec(96, iv); 

     // encrypt 
     Cipher cipher = Cipher.getInstance(algo); 
     System.out.println(String.format("CEK Cipher alg:%S provider:%S", cipher.getAlgorithm(), 
       cipher.getProvider().getName())); 

     cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(digest, "AES"), gspec); 
     byte[] result = cipher.doFinal(cek.getEncoded()); 

     System.out.println(String.format("Encrypted CEK :%S", toBase64(result))); 

    } catch (NoSuchAlgorithmException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (UnsupportedEncodingException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (InvalidKeyException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (InvalidAlgorithmParameterException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (NoSuchPaddingException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (IllegalBlockSizeException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (BadPaddingException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

です。

+0

問題声明に予想される入力/出力を追加します。 – erickson

答えて

4

はい、VisaトークンサービスはJWE(今はRFC 7516)を使用しているようですので、jose4jを使用することができます。ここでは暗号化および復号化A256GCMKWを使用してJWEといくつかのコンテンツをしてAGCM256示したいくつかのサンプルコードです:

// shared secret hashed to key from your example 
    String shared_secret = "[email protected]//x1LwM123QP/ln"; 
    MessageDigest md = MessageDigest.getInstance("SHA-256"); 
    byte[] digest = md.digest(shared_secret.getBytes("UTF-8")); 

    JsonWebEncryption jwe = new JsonWebEncryption(); 

    // A256GCMKW for key wrap 
    jwe.setAlgorithmHeaderValue(KeyManagementAlgorithmIdentifiers.A256GCMKW); 

    // A256GCM for content encryption 
    jwe.setEncryptionMethodHeaderParameter(ContentEncryptionAlgorithmIdentifiers.AES_256_GCM); 

    // the key (from above) 
    jwe.setKey(new SecretKeySpec(digest, "AES")); 

    // whatever content you want to encrypt 
    jwe.setPayload("some important content to be encrypted and integrity protected"); 

    // Produce the JWE compact serialization, which is where the actual encryption is done. 
    // The JWE compact serialization consists of five base64url encoded parts 
    // combined with a dot ('.') character in the general format of 
    // <header>.<encrypted key>.<initialization vector>.<ciphertext>.<authentication tag> 
    String serializedJwe = jwe.getCompactSerialization(); 


    // Do something with the JWE. Like send it to some other party over the clouds 
    // and through the interwebs. 
    System.out.println("JWE compact serialization: " + serializedJwe); 

    // That other party, the receiver, can then use JsonWebEncryption to decrypt the message. 
    JsonWebEncryption receiverJwe = new JsonWebEncryption(); 

    // Set the compact serialization on new Json Web Encryption object 
    receiverJwe.setCompactSerialization(serializedJwe); 

    // Symmetric encryption, like we are doing here, requires that both parties have the same key. 
    // The key will have had to have been securely exchanged out-of-band somehow. 
    receiverJwe.setKey(new SecretKeySpec(digest, "AES")); 

    // Get the message that was encrypted in the JWE. This step performs the actual decryption steps. 
    String plaintext = receiverJwe.getPlaintextString(); 

    // And do whatever you need to do with the clear text message. 
    System.out.println("plaintext: " + plaintext); 
+0

ブライアンありがとう、私はちょうどJava暗号を直接使用することと比較してそれを使いました。 – iuq

1

実際にGCMモードでAESが必要であるとしましょう(私はAGCMについて聞いたことがありませんが、これはAES/GCMを意味するという論理的な前提です)。次に、秘密鍵をラッピングするために以下を使用することができます。少なくとも、Oracle JCEではなく、IvParameterSpecを使用してこれを動作させることはできませんでした。あなたは(IVを格納する例に示されていないラップされた鍵と一緒にIV 認証タグを格納する必要がないんとしてSIVモードを使用すると、おそらく多少キーを包むために好まれるべきであると

SecretKey sk = new SecretKeySpec(new byte[16], "AES"); 
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); 
GCMParameterSpec gcmSpec = new GCMParameterSpec(128, new byte[12]); 
cipher.init(Cipher.WRAP_MODE, sk, gcmSpec); 
byte[] wrappedKey = cipher.wrap(sk); 
System.out.println(Hex.toHexString(wrappedKey)); 

cipher.init(Cipher.UNWRAP_MODE, sk, gcmSpec); 
SecretKey unwrap = (SecretKey) cipher.unwrap(wrappedKey, "AES", Cipher.SECRET_KEY); 
System.out.println(Hex.toHexString(unwrap.getEncoded())); 

注意)。上記のコードは、セキュリティのための固有のIV(図示せず)に依存しています。

明らかに、自分自身でキーをラップすることも良い考えではありません。申し訳ありませんが、私はここで少し怠惰です。私はちょうど暗号を使用する方法を示しました。

1

「KW」は、RFC 3394で定義されている「キーラッピング」を指します。このアルゴリズムの名前は「AESWrap」です。変換は「AESWrap/GCM/NoPadding」にする必要があります。 Maarten氏が指摘しているように、論理的にはこの操作でCipherWRAP_MODEに設定する必要があります。

関連する問題