下面列出了怎么用org.bouncycastle.crypto.params.KDFCounterParameters的API类实例代码及写法,或者点击链接到github查看源代码。
public static byte[]
ctrHMac(byte[] keyDerivationKey, byte[] label, Supplier<Digest> digestSupplier, int keyLengthBytes) {
logger.trace("<< ctrHMac() - keyDerivationKey: 0x{} label: {} digestSupplier: {} length: {}",
Hex.toHexString(keyDerivationKey), Hex.toHexString(label), digestSupplier, keyLengthBytes);
byte[] derivedKey = new byte[keyLengthBytes];
// fixedInputData = label || 0x00 || dkLen in bits as 4 bytes big endian
ByteBuffer buffer = ByteBuffer.allocate(label.length + 5);
buffer.put(label);
buffer.put((byte) 0);
buffer.putInt(keyLengthBytes * 8);
byte[] fixedInputData = buffer.array();
logger.debug("-- ctrHMac() - fixed input data: 0x{}", Hex.toHexString(fixedInputData));
HMac hMac = new HMac(digestSupplier.get());
KDFCounterBytesGenerator generator = new KDFCounterBytesGenerator(hMac);
generator.init(new KDFCounterParameters(keyDerivationKey, fixedInputData, R));
generator.generateBytes(derivedKey, 0, derivedKey.length);
logger.trace(">> ctrHMac() - derivedKey: 0x{}", Hex.toHexString(derivedKey));
return derivedKey;
}
private static byte[] scp03_kdf(byte[] key, byte[] a, byte[] b, int bytes) {
BlockCipher cipher = new AESEngine();
CMac cmac = new CMac(cipher);
KDFCounterBytesGenerator kdf = new KDFCounterBytesGenerator(cmac);
kdf.init(new KDFCounterParameters(key, a, b, 8));
byte[] cgram = new byte[bytes];
kdf.generateBytes(cgram, 0, cgram.length);
return cgram;
}
/**
* @param sessionKey
* @param label
* @param context
*/
private static byte[] derive ( byte[] sessionKey, byte[] label, byte[] context ) {
KDFCounterBytesGenerator gen = new KDFCounterBytesGenerator(new HMac(new SHA256Digest()));
int r = 32;
byte[] suffix = new byte[label.length + context.length + 5];
// per bouncycastle
// <li>1: K(i) := PRF( KI, [i]_2 || Label || 0x00 || Context || [L]_2 ) with the counter at the very beginning
// of the fixedInputData (The default implementation has this format)</li>
// with the parameters
// <li>1. KDFCounterParameters(ki, null, "Label || 0x00 || Context || [L]_2]", 8);
// all fixed inputs go into the suffix:
// + label
System.arraycopy(label, 0, suffix, 0, label.length);
// + 1 byte 0x00
// + context
System.arraycopy(context, 0, suffix, label.length + 1, context.length);
// + 4 byte (== r bits) big endian encoding of L
suffix[ suffix.length - 1 ] = (byte) 128;
DerivationParameters param = new KDFCounterParameters(sessionKey, null /* prefix */, suffix /* suffix */, r /* r */);
gen.init(param);
byte[] derived = new byte[16];
gen.generateBytes(derived, 0, 16);
return derived;
}
/**
* @param sessionKey
* @param label
* @param context
*/
private static byte[] derive ( byte[] sessionKey, byte[] label, byte[] context ) {
KDFCounterBytesGenerator gen = new KDFCounterBytesGenerator(new HMac(new SHA256Digest()));
int r = 32;
byte[] suffix = new byte[label.length + context.length + 5];
// per bouncycastle
// <li>1: K(i) := PRF( KI, [i]_2 || Label || 0x00 || Context || [L]_2 ) with the counter at the very beginning
// of the fixedInputData (The default implementation has this format)</li>
// with the parameters
// <li>1. KDFCounterParameters(ki, null, "Label || 0x00 || Context || [L]_2]", 8);
// all fixed inputs go into the suffix:
// + label
System.arraycopy(label, 0, suffix, 0, label.length);
// + 1 byte 0x00
// + context
System.arraycopy(context, 0, suffix, label.length + 1, context.length);
// + 4 byte (== r bits) big endian encoding of L
suffix[ suffix.length - 1 ] = (byte) 128;
DerivationParameters param = new KDFCounterParameters(sessionKey, null /* prefix */, suffix /* suffix */, r /* r */);
gen.init(param);
byte[] derived = new byte[16];
gen.generateBytes(derived, 0, 16);
return derived;
}
public static byte[] scp03_kdf(byte[] key, byte[] a, byte[] b, int bytes) {
BlockCipher cipher = new AESEngine();
CMac cmac = new CMac(cipher);
KDFCounterBytesGenerator kdf = new KDFCounterBytesGenerator(cmac);
kdf.init(new KDFCounterParameters(key, a, b, 8)); // counter size is in bits
byte[] cgram = new byte[bytes];
kdf.generateBytes(cgram, 0, cgram.length);
return cgram;
}