2016-06-30 4 views
2

Bezug this, muss ich mit Algorithmus AGCM256-KW verschlüsseln. Ich benutze Java Cryptography und ich habe keinen solchen Algorithmus gefunden. Am nächsten fand ich AES_256/GCM/NoPadding aber es hat kein KW (Key Wrapping).Wie lautet die Algorithmuszeichenfolge für 'AGCM256-KW' in der Java-Kryptographie, die in Cipher.getInstance (String algo) verwendet werden soll?

hier ist mein Testcode

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(); 
    } 
} 

Update 1 Ich glaube, ich jose4j Bibliothek verwenden können, die APIs für JWE hat.

+0

Add erwartete Eingabe/Ausgabe auf Ihre Problemstellung. – erickson

Antwort

4

Ja, die Visa Token Services scheinen JWE (jetzt RFC 7516) zu verwenden, so dass Sie jose4j dafür verwenden können. Hier ist ein Beispielcode, der zeigt, Verschlüsselung und einige Inhalte mit JWE Entschlüsseln A256GCMKW und AGCM256 mit:

// 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

Dank Brian, ich habe genau das und seine einfache im Vergleich zur Verwendung von Java-Kryptographie direkt verwendet. – iuq

1

Nehmen wir an, Sie benötigen tatsächlich AES im GCM-Modus (ich habe noch nie von AGCM gehört, aber ich denke, das ist eine logische Annahme, dass es AES/GCM bedeutet). Dann könnte das Folgende zum Entpacken eines geheimen Schlüssels verwendet werden. Beachten Sie, dass ich dies nicht mit IvParameterSpec funktioniert, zumindest nicht für die Oracle JCE.

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())); 

Beachten Sie, dass SIV-Modus soll wohl etwas zum Einwickeln von Tasten bevorzugt werden, da Sie nicht benötigen ein IV und Authentifizierung Tag zu speichern, zusammen mit der umwickelten Taste (die IV-Speicherung wird im Beispiel nicht gezeigt). Der obige Code beruht auf einer eindeutigen IV für die Sicherheit (ebenfalls nicht gezeigt).

Offensichtlich ist es auch keine gute Idee, einen Schlüssel mit sich selbst zu wickeln. Entschuldigung, ich bin hier ein bisschen faul geworden; Ich habe gerade gezeigt, wie man die Chiffre benutzt.

1

Die "KW" bezieht sich auf "Key-Wrapping", wie in RFC 3394 definiert. Der Name für diesen Algorithmus in der JCE ist "AESWrap". Die Transformation sollte also "AESWrap/GCM/NoPadding" sein. Wie Maarten darauf hingewiesen hat, sollte diese Operation logisch Cipher in WRAP_MODE konfigurieren.

Verwandte Themen