私は暗号化と復号化が初めてです。PSKC ファイルを渡され、復号化を求められました。復号化のためのパスワードが与えられました。PSKC ファイルには初期化ベクトル値がありません。私はそれを解読しようとするコードを書きました。しかし、私は結果を達成することに失敗しています。以下はPSKCファイルの例です
<?xml version="1.0"?>
<pskc:KeyContainer xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:pkcs5="http://www.rsasecurity.com/rsalabs/pkcs/schemas/pkcs-5v2-0#" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" xmlns:xenc11="http://www.w3.org/2009/xmlenc11#" xmlns:pskc="urn:ietf:params:xml:ns:keyprov:pskc">
<pskc:EncryptionKey>
<xenc11:DerivedKey xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" xmlns:pkcs5="http://www.rsasecurity.com/rsalabs/pkcs/schemas/pkcs-5v2-0#" xmlns:pskc="urn:ietf:params:xml:ns:keyprov:pskc" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xenc11="http://www.w3.org/2009/xmlenc11#">
<xenc11:KeyDerivationMethod Algorithm="http://www.rsasecurity.com/rsalabs/pkcs/schemas/pkcs-5v2-0#pbkdf2">
<pkcs5:PBKDF2-params xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" xmlns:pskc="urn:ietf:params:xml:ns:keyprov:pskc" xmlns:xenc11="http://www.w3.org/2009/xmlenc11#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:pkcs5="http://www.rsasecurity.com/rsalabs/pkcs/schemas/pkcs-5v2-0#">
<Salt>
<Specified>EW0h0yUcDX72WU9UiKiCwDpXsJg=</Specified>
</Salt>
<IterationCount>128</IterationCount>
<KeyLength>16</KeyLength>
<PRF />
</pkcs5:PBKDF2-params>
</xenc11:KeyDerivationMethod>
<xenc:ReferenceList>
<xenc:DataReference URI="#ED" />
</xenc:ReferenceList>
<xenc11:MasterKeyName>Passphrase1</xenc11:MasterKeyName>
</xenc11:DerivedKey>
</pskc:EncryptionKey>
<pskc:MACMethod Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1">
<pskc:MACKey>
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc" />
<xenc:CipherData>
<xenc:CipherValue>jq/NdikC7AZf0Z+HEL5NrCICV8XW+ttzl/8687hVGHceoyJAaFws+111plQH6Mlg</xenc:CipherValue>
</xenc:CipherData>
</pskc:MACKey>
</pskc:MACMethod>
<pskc:KeyPackage>
<pskc:DeviceInfo>
<pskc:Manufacturer>Gemalto</pskc:Manufacturer>
<pskc:SerialNo>GAKT000047A5</pskc:SerialNo>
</pskc:DeviceInfo>
<pskc:CryptoModuleInfo>
<pskc:Id>CM_ID_007</pskc:Id>
</pskc:CryptoModuleInfo>
<pskc:Key Id="GAKT000047A5" Algorithm="urn:ietf:params:xml:ns:keyprov:pskc:totp">
<pskc:Issuer>Issuer0</pskc:Issuer>
<pskc:AlgorithmParameters>
<pskc:ResponseFormat Encoding="DECIMAL" Length="6" />
</pskc:AlgorithmParameters>
<pskc:Data>
<pskc:Secret>
<pskc:EncryptedValue>
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc" />
<xenc:CipherData>
<xenc:CipherValue>pM7VB/KomPjq2cKaxPr5cKT1tUZN5tGMI+u1XKJTG1la+ThraPpLKlL2plKk6vQE</xenc:CipherValue>
</xenc:CipherData>
</pskc:EncryptedValue>
<pskc:ValueMAC>lbu+9OcLArnj6mS7KYOKDa4zRU0=</pskc:ValueMAC>
</pskc:Secret>
<pskc:Time>
<pskc:PlainValue>0</pskc:PlainValue>
</pskc:Time>
<pskc:TimeInterval>
<pskc:PlainValue>30</pskc:PlainValue>
</pskc:TimeInterval>
</pskc:Data>
</pskc:Key>
</pskc:KeyPackage>
</pskc:KeyContainer>
以下は、復号化のために私が書いたJavaコードです。
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import javax.crypto.Cipher;
import javax.crypto.Mac;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin;
public class test {
/**
* @param args
*/
public static void main(String[] args) {
test te = new test();
try {
te.decryptSeedValue();
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println(e.getMessage());
e.printStackTrace();
}
// TODO Auto-generated method stub
}
public static HashMap decryptSeedValue()throws Exception{
String password = "G?20R+I+3-/UcWIN";
String pbesalt ="EW0h0yUcDX72WU9UiKiCwDpXsJg=";
String iv = "aaaaaaaaaaaaaaaaaaaaaaaa";
int iteration = 128;
String value = "pM7VB/KomPjq2cKaxPr5cKT1tUZN5tGMI+u1XKJTG1la+ThraPpLKlL2plKk6vQE";
String valueDigest = "lbu+9OcLArnj6mS7KYOKDa4zRU0=";
byte[] cipherText =null;
//some parameters need to decode from Base64 to byte[]
byte[] data = base64Decode(value.getBytes());
//System.out.println("data(hex string) = " + HexBin.encode(data));//debug
byte[] salt = base64Decode(pbesalt.getBytes());
//System.out.println("salt(hex string) = " + HexBin.encode(salt));//debug
byte[] initVec = base64Decode(iv.getBytes());
//System.out.println("iv(hex string) = " + HexBin.encode(initVec));//debug
//perform PBE key generation and AES/CBC/PKCS5Padding decrpyption
HashMap hs = myFunction(data, password, initVec, salt, iteration);
String seedValue = (String)hs.get("DECRYPTED_SEED_VALUE");
byte[] temp = (byte[])hs.get("HASH_OUTPUT");
//System.out.println("hashed output(hex string) = " + HexBin.encode(temp));//debug
//perform Base64 Encode
byte[] out = base64Encode(temp);
String output = new String((out));
System.out.println("output = "+output);
System.out.println("valueD = "+valueDigest);
//System.out.println("hashed output(base64) = " + output);
//compare the result
if(output.equals(valueDigest)){
System.out.println("Hash verification successful for:-->" );
System.out.println("\n");
//hs.put("SEED_VALUE", HexBin.encode(temp));
hs.put("SEED_VALUE", seedValue);
return hs;
}
else{
System.out.println("Hash verification failed for :-->");
return null;
}
}
public static HashMap myFunction(byte[] data, String password, byte[] initVec,
byte[] salt, int iteration) throws Exception{
PKCS5S2ParametersGenerator generator = new PKCS5S2ParametersGenerator();
byte[] pBytes = password.getBytes();
generator.init(pBytes, salt, iteration);
int keysize = 128;//fixed at AES key of 16 bytes
int ivsize = initVec.length;
ParametersWithIV params = (ParametersWithIV) generator.generateDerivedParameters(keysize, ivsize);
KeyParameter keyParam = (KeyParameter) params.getParameters();
//System.out.println("derived key = " + HexBin.encode(keyParam.getKey()));
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec paramSpec = new IvParameterSpec(initVec);
SecretKeySpec key = new SecretKeySpec(keyParam.getKey(), "AES");
cipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
//perform decryption
byte[] secret = cipher.doFinal(data);
//display the 20 bytes secret of the token
//System.out.println("token secret(hex string) = " + HexBin.encode(secret));
//perform HMAC-SHA-1
byte[] output = hmac_sha1(secret, keyParam.getKey());
HashMap hs = new HashMap();
hs.put("ENCRYPTION_KEY", HexBin.encode(keyParam.getKey()));
hs.put("HASH_OUTPUT", output);
hs.put("DECRYPTED_SEED_VALUE", HexBin.encode(secret));
return hs;
}
public static byte[] base64Encode(byte[] passwordBytes) throws NoSuchAlgorithmException {
Base64 base64 = new Base64();
byte[] hashBytes2 = base64.encode(passwordBytes);
return hashBytes2;
}
public static byte[] base64Decode(byte[] passwordBytes) throws NoSuchAlgorithmException {
Base64 base64 = new Base64();
byte[] hashBytes2 = base64.decode(passwordBytes);
return hashBytes2;
}
public static byte[] hmac_sha1(byte[] dataByte, byte[] keyByte) throws Exception{
Mac hmacSha1;
hmacSha1 = Mac.getInstance("HmacSHA1");
SecretKeySpec macKey = new SecretKeySpec(keyByte, "HmacSHA1");
hmacSha1.init(macKey);
byte[] result = hmacSha1.doFinal(dataByte);
return result;
}
/**
* Convert a byte array of 8 bit characters into a String.
*
* @param bytes the array containing the characters
* @param length the number of bytes to process
* @return a String representation of bytes
*/
private static String toString(
byte[] bytes,
int length)
{
char[] chars = new char[length];
for (int i = 0; i != chars.length; i++)
{
chars[i] = (char)(bytes[i] & 0xff);
}
return new String(chars);
}
}
例外はスローされませんが、復号化が失敗したときにコードで定義されている「ハッシュ検証に失敗しました」が出力されます。誰かが私を助けてくれませんか。