下面列出了javax.crypto.Mac#update ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* NULL ByteBuffer test case. Pass NULL ByteBuffer to Mac.update(ByteBuffer
* buffer) method. An IllegalArgumentException expected.
*
* @param theMac Mac object to test.
* @return true - test case pass; false - otherwise.
*/
protected boolean nullByteBufferTest(Mac theMac) {
try {
ByteBuffer buf = null;
theMac.update(buf);
theMac.doFinal();
} catch (IllegalArgumentException e) {
// expected exception has been thrown
return true;
}
System.out.println("FAIL: "
+ "IllegalArgumentException hasn't been thrown as expected");
return false;
}
@Override
public void doTest(String alg) throws NoSuchAlgorithmException,
InvalidKeyException, NoSuchProviderException {
SecretKey key = Utils.getSecretKeySpec();
// instantiate Mac object and init it with a SecretKey
Mac mac = Mac.getInstance(alg, "SunJCE");
mac.init(key);
// prepare buffer
byte[] data = new byte[0];
ByteBuffer buf = ByteBuffer.wrap(data);
mac.update(buf);
mac.doFinal();
}
/**
* Generates the SCRAM salted password. See section 3 of RFC 5802.
*
* @param passwordBytes
* The password bytes.
* @return The salted password.
* @throws SaslException
* On a failure to initialize the {@link Mac}.
*/
private byte[] generateSaltedPassword(final byte[] passwordBytes)
throws SaslException {
final Mac mac = initMac(passwordBytes);
mac.update(mySalt);
mac.update(ONE_UINT32_BE);
final byte[] result = mac.doFinal();
byte[] previous = result;
for (int i = 1; i < myIterationCount; i++) {
previous = mac.doFinal(previous);
for (int x = 0; x < result.length; x++) {
result[x] ^= previous[x];
}
}
return result;
}
/**
* Constant-time equality check.
*/
private boolean safeEquals(ByteBuffer signature, byte[] calculatedSig) {
try {
signature.rewind();
Mac hmac = Mac.getInstance(hmacComparisonKey.getAlgorithm());
hmac.init(hmacComparisonKey);
hmac.update(signature);
byte[] signatureHash = hmac.doFinal();
hmac.reset();
hmac.update(calculatedSig);
byte[] calculatedHash = hmac.doFinal();
return MessageDigest.isEqual(signatureHash, calculatedHash);
} catch (GeneralSecurityException ex) {
// We've hardcoded these algorithms, so the error should not be possible.
throw new RuntimeException("Unexpected exception", ex);
}
}
public static String generateHmacSha256Hash(String key, String valueToEncrypt)
{
try {
SecretKeySpec secretKey = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(secretKey);
mac.update(valueToEncrypt.getBytes("UTF-8"));
byte[] hmacData = mac.doFinal();
return Base64.getEncoder().encodeToString(hmacData);
}
catch (UnsupportedEncodingException | IllegalStateException | InvalidKeyException | NoSuchAlgorithmException e) {
throw new RuntimeException("CommunityCommons::EncodeHmacSha256::Unable to encode: " + e.getMessage(), e);
}
}
public static String generateAccessSignature(SecretKeySpec secret, UUID recordingId, long expTime) {
try {
byte[] expTimeBytes = ByteBuffer.allocate(8).putLong(expTime).array();
byte[] recordingIdBytes = recordingId.toString().getBytes(StandardCharsets.UTF_8);
Mac hmac = Mac.getInstance("HmacSHA256");
hmac.init(secret);
hmac.update(recordingIdBytes);
byte[] result = hmac.doFinal(expTimeBytes);
return Base64.getEncoder().encodeToString(result);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
/**
* {@code signature = hmac(integrityKey, payload || initVector)}
*/
private int hmacSignature(byte[] workBytes) {
try {
Mac integrityHmac = createMac();
integrityHmac.init(keys.getIntegrityKey());
integrityHmac.update(workBytes, PAYLOAD_BASE, workBytes.length - OVERHEAD_SIZE);
integrityHmac.update(workBytes, INITV_BASE, INITV_SIZE);
return Ints.fromByteArray(integrityHmac.doFinal());
} catch (InvalidKeyException e) {
throw new IllegalStateException(e);
}
}
public static byte[] sign(byte[] data, Algorithm algorithm, SecretKey key) {
try {
Mac mac = getMAC(algorithm);
mac.init(key);
mac.update(data);
return mac.doFinal();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void doTest(String algo) throws NoSuchAlgorithmException,
NoSuchProviderException, InvalidKeyException {
Mac mac;
try {
mac = Mac.getInstance(algo, "SunJCE");
} catch (NoSuchAlgorithmException nsae) {
// depending on Solaris configuration,
// it can support HMAC or not with Mac
System.out.println("Expected NoSuchAlgorithmException thrown: "
+ nsae);
return;
}
byte[] plain = new byte[MESSAGE_SIZE];
for (int i = 0; i < MESSAGE_SIZE; i++) {
plain[i] = (byte) (i % 256);
}
byte[] tail = new byte[plain.length - OFFSET];
System.arraycopy(plain, OFFSET, tail, 0, tail.length);
SecureRandom srdm = new SecureRandom();
byte[] keyVal = new byte[KEY_SIZE];
srdm.nextBytes(keyVal);
SecretKeySpec keySpec = new SecretKeySpec(keyVal, "HMAC");
mac.init(keySpec);
byte[] result1 = mac.doFinal(plain);
mac.reset();
mac.update(plain[0]);
mac.update(plain, 1, OFFSET - 1);
byte[] result2 = mac.doFinal(tail);
if (!java.util.Arrays.equals(result1, result2)) {
throw new RuntimeException("result1 and result2 are not the same");
}
}
@Override
public void doTest(String alg) throws NoSuchAlgorithmException,
InvalidKeyException, NoSuchProviderException {
SecretKey key = Utils.getSecretKeySpec();
// instantiate Mac object and init it with a SecretKey
Mac mac = Mac.getInstance(alg, "SunJCE");
mac.init(key);
// prepare buffer
byte[] data = new byte[BUFFER_SIZE];
for (int i = 0; i < BUFFER_SIZE; i++) {
data[i] = (byte) (i % 256);
}
ByteBuffer buf = ByteBuffer.wrap(data);
int limitBefore = buf.limit();
mac.update(buf);
mac.doFinal();
int limitAfter = buf.limit();
int positonAfter = buf.position();
if (limitAfter != limitBefore) {
System.out.println("limit after = " + limitAfter);
System.out.println("limit before = " + limitBefore);
throw new RuntimeException("Test failed: "
+ "limit of buffer has been chenged.");
}
if (positonAfter != limitAfter) {
System.out.println("position after = " + positonAfter);
System.out.println("limit after = " + limitAfter);
throw new RuntimeException("Test failed: "
+ "position of buffer isn't equal to its limit");
}
}
private byte[] calculateMac(char[] passwd, byte[] data)
throws IOException
{
byte[] mData = null;
String algName = macAlgorithm.substring(7);
try {
// Generate a random salt.
byte[] salt = getSalt();
// generate MAC (MAC key is generated within JCE)
Mac m = Mac.getInstance(macAlgorithm);
PBEParameterSpec params =
new PBEParameterSpec(salt, macIterationCount);
SecretKey key = getPBEKey(passwd);
m.init(key, params);
m.update(data);
byte[] macResult = m.doFinal();
// encode as MacData
MacData macData = new MacData(algName, macResult, salt,
macIterationCount);
DerOutputStream bytes = new DerOutputStream();
bytes.write(macData.getEncoded());
mData = bytes.toByteArray();
} catch (Exception e) {
throw new IOException("calculateMac failed: " + e, e);
}
return mData;
}
@NonNull
private byte[] createMac(@NonNull byte[] cipher, @NonNull byte[] iv) throws GeneralSecurityException {
Mac mac = Mac.getInstance(MAC_ALGORITHM);
mac.init(mMacKey);
mac.update(cipher);
mac.update(iv);
return mac.doFinal();
}
/**
* Implementation of PBKDF2 (RFC2898).
*
* @param mac Pre-initialized {@link Mac} instance to use.
* @param S Salt.
* @param c Iteration count.
* @param DK Byte array that derived key will be placed in.
* @param dkLen Intended length, in octets, of the derived key.
*
* @throws GeneralSecurityException
*/
public static void pbkdf2(Mac mac, byte[] S, int c, byte[] DK, int dkLen) throws GeneralSecurityException {
int hLen = mac.getMacLength();
if (dkLen > (Math.pow(2, 32) - 1) * hLen) {
throw new GeneralSecurityException("Requested key length too long");
}
byte[] U = new byte[hLen];
byte[] T = new byte[hLen];
byte[] block1 = new byte[S.length + 4];
int l = (int) Math.ceil((double) dkLen / hLen);
int r = dkLen - (l - 1) * hLen;
arraycopy(S, 0, block1, 0, S.length);
for (int i = 1; i <= l; i++) {
block1[S.length + 0] = (byte) (i >> 24 & 0xff);
block1[S.length + 1] = (byte) (i >> 16 & 0xff);
block1[S.length + 2] = (byte) (i >> 8 & 0xff);
block1[S.length + 3] = (byte) (i >> 0 & 0xff);
mac.update(block1);
mac.doFinal(U, 0);
arraycopy(U, 0, T, 0, hLen);
for (int j = 1; j < c; j++) {
mac.update(U);
mac.doFinal(U, 0);
for (int k = 0; k < hLen; k++) {
T[k] ^= U[k];
}
}
arraycopy(T, 0, DK, (i - 1) * hLen, (i == l ? r : hLen));
}
}
private void doTest(String algo, Provider provider)
throws NoSuchAlgorithmException, NoSuchProviderException,
InvalidKeyException {
System.out.println("Test " + algo);
Mac mac;
try {
mac = Mac.getInstance(algo, provider);
} catch (NoSuchAlgorithmException nsae) {
if ("SunPKCS11-Solaris".equals(provider.getName())) {
// depending on Solaris configuration,
// it can support HMAC or not with Mac
System.out.println("Expected NoSuchAlgorithmException thrown: "
+ nsae);
return;
}
throw nsae;
}
byte[] plain = new byte[MESSAGE_SIZE];
for (int i = 0; i < MESSAGE_SIZE; i++) {
plain[i] = (byte) (i % 256);
}
byte[] tail = new byte[plain.length - OFFSET];
System.arraycopy(plain, OFFSET, tail, 0, tail.length);
SecureRandom srdm = new SecureRandom();
byte[] keyVal = new byte[KEY_SIZE];
srdm.nextBytes(keyVal);
SecretKeySpec keySpec = new SecretKeySpec(keyVal, "HMAC");
mac.init(keySpec);
byte[] result1 = mac.doFinal(plain);
mac.reset();
mac.update(plain[0]);
mac.update(plain, 1, OFFSET - 1);
byte[] result2 = mac.doFinal(tail);
if (!java.util.Arrays.equals(result1, result2)) {
throw new RuntimeException("result1 and result2 are not the same");
}
}
private static byte[] deriveKey(final Mac prf, final byte[] password,
byte[] salt, int iterCount, int keyLengthInBit) {
int keyLength = keyLengthInBit/8;
byte[] key = new byte[keyLength];
try {
int hlen = prf.getMacLength();
int intL = (keyLength + hlen - 1)/hlen; // ceiling
int intR = keyLength - (intL - 1)*hlen; // residue
byte[] ui = new byte[hlen];
byte[] ti = new byte[hlen];
// SecretKeySpec cannot be used, since password can be empty here.
SecretKey macKey = new SecretKey() {
private static final long serialVersionUID = 7874493593505141603L;
@Override
public String getAlgorithm() {
return prf.getAlgorithm();
}
@Override
public String getFormat() {
return "RAW";
}
@Override
public byte[] getEncoded() {
return password;
}
@Override
public int hashCode() {
return Arrays.hashCode(password) * 41 +
prf.getAlgorithm().toLowerCase(Locale.ENGLISH).hashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (this.getClass() != obj.getClass()) return false;
SecretKey sk = (SecretKey)obj;
return prf.getAlgorithm().equalsIgnoreCase(
sk.getAlgorithm()) &&
MessageDigest.isEqual(password, sk.getEncoded());
}
};
prf.init(macKey);
byte[] ibytes = new byte[4];
for (int i = 1; i <= intL; i++) {
prf.update(salt);
ibytes[3] = (byte) i;
ibytes[2] = (byte) ((i >> 8) & 0xff);
ibytes[1] = (byte) ((i >> 16) & 0xff);
ibytes[0] = (byte) ((i >> 24) & 0xff);
prf.update(ibytes);
prf.doFinal(ui, 0);
System.arraycopy(ui, 0, ti, 0, ui.length);
for (int j = 2; j <= iterCount; j++) {
prf.update(ui);
prf.doFinal(ui, 0);
// XOR the intermediate Ui's together.
for (int k = 0; k < ui.length; k++) {
ti[k] ^= ui[k];
}
}
if (i == intL) {
System.arraycopy(ti, 0, key, (i-1)*hlen, intR);
} else {
System.arraycopy(ti, 0, key, (i-1)*hlen, hlen);
}
}
} catch (GeneralSecurityException gse) {
throw new RuntimeException("Error deriving PBKDF2 keys");
}
return key;
}
public static byte[] computeHmac(final byte[] key, final String string)
throws SaslException {
Mac mac = createSha1Hmac(key);
mac.update(string.getBytes(StandardCharsets.UTF_8));
return mac.doFinal();
}
private static void runTest(DataTuple dataTuple)
throws NoSuchAlgorithmException, NoSuchProviderException,
InvalidKeyException {
Mac mcAlgorithm = Mac.getInstance(dataTuple.algorithm,
PROVIDER_NAME);
Mac mcOid = Mac.getInstance(dataTuple.oid, PROVIDER_NAME);
if (mcAlgorithm == null) {
throw new RuntimeException(String.format(
"Test failed: Mac using algorithm "
+ "string %s getInstance failed.%n",
dataTuple.algorithm));
}
if (mcOid == null) {
throw new RuntimeException(String.format(
"Test failed: Mac using OID %s getInstance failed.%n",
dataTuple.oid));
}
if (!mcAlgorithm.getAlgorithm().equals(dataTuple.algorithm)) {
throw new RuntimeException(String.format(
"Test failed: Mac using algorithm string %s getInstance "
+ "doesn't generate expected algorithm.%n",
dataTuple.algorithm));
}
KeyGenerator kg = KeyGenerator.getInstance(dataTuple.algorithm,
PROVIDER_NAME);
SecretKey key = kg.generateKey();
mcAlgorithm.init(key);
mcAlgorithm.update(INPUT);
mcOid.init(key);
mcOid.update(INPUT);
// Comparison
if (!Arrays.equals(mcAlgorithm.doFinal(), mcOid.doFinal())) {
throw new RuntimeException("Digest comparison failed: "
+ "the two MACs are not the same");
}
}
private static byte[] deriveKey(final Mac prf, final byte[] password,
byte[] salt, int iterCount, int keyLengthInBit) {
int keyLength = keyLengthInBit/8;
byte[] key = new byte[keyLength];
try {
int hlen = prf.getMacLength();
int intL = (keyLength + hlen - 1)/hlen; // ceiling
int intR = keyLength - (intL - 1)*hlen; // residue
byte[] ui = new byte[hlen];
byte[] ti = new byte[hlen];
// SecretKeySpec cannot be used, since password can be empty here.
SecretKey macKey = new SecretKey() {
private static final long serialVersionUID = 7874493593505141603L;
@Override
public String getAlgorithm() {
return prf.getAlgorithm();
}
@Override
public String getFormat() {
return "RAW";
}
@Override
public byte[] getEncoded() {
return password;
}
@Override
public int hashCode() {
return Arrays.hashCode(password) * 41 +
prf.getAlgorithm().toLowerCase(Locale.ENGLISH).hashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (this.getClass() != obj.getClass()) return false;
SecretKey sk = (SecretKey)obj;
return prf.getAlgorithm().equalsIgnoreCase(
sk.getAlgorithm()) &&
Arrays.equals(password, sk.getEncoded());
}
};
prf.init(macKey);
byte[] ibytes = new byte[4];
for (int i = 1; i <= intL; i++) {
prf.update(salt);
ibytes[3] = (byte) i;
ibytes[2] = (byte) ((i >> 8) & 0xff);
ibytes[1] = (byte) ((i >> 16) & 0xff);
ibytes[0] = (byte) ((i >> 24) & 0xff);
prf.update(ibytes);
prf.doFinal(ui, 0);
System.arraycopy(ui, 0, ti, 0, ui.length);
for (int j = 2; j <= iterCount; j++) {
prf.update(ui);
prf.doFinal(ui, 0);
// XOR the intermediate Ui's together.
for (int k = 0; k < ui.length; k++) {
ti[k] ^= ui[k];
}
}
if (i == intL) {
System.arraycopy(ti, 0, key, (i-1)*hlen, intR);
} else {
System.arraycopy(ti, 0, key, (i-1)*hlen, hlen);
}
}
} catch (GeneralSecurityException gse) {
throw new RuntimeException("Error deriving PBKDF2 keys");
}
return key;
}
/**
* Create signature for JWT header and payload.
*
* @param algorithm algorithm name.
* @param secretBytes algorithm secret.
* @param headerBytes JWT header.
* @param payloadBytes JWT payload.
* @return the signature bytes.
* @throws NoSuchAlgorithmException if the algorithm is not supported.
* @throws InvalidKeyException if the given key is inappropriate for initializing the specified algorithm.
*/
byte[] createSignatureFor(String algorithm, byte[] secretBytes, byte[] headerBytes, byte[] payloadBytes) throws NoSuchAlgorithmException, InvalidKeyException {
final Mac mac = Mac.getInstance(algorithm);
mac.init(new SecretKeySpec(secretBytes, algorithm));
mac.update(headerBytes);
mac.update(JWT_PART_SEPARATOR);
return mac.doFinal(payloadBytes);
}
/**
* Updates the given {@link Mac}. This generates a digest for valueToDigest and the key the Mac was initialized
*
* @param mac
* the initialized {@link Mac} to update
* @param valueToDigest
* the value to update the {@link Mac} with (maybe null or empty)
* @return the updated {@link Mac}
* @throws IllegalStateException
* if the Mac was not initialized
* @since 1.x
*/
public static Mac updateHmac(final Mac mac, final byte[] valueToDigest) {
mac.reset();
mac.update(valueToDigest);
return mac;
}