下面列出了怎么用javax.crypto.Mac的API类实例代码及写法,或者点击链接到github查看源代码。
@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();
}
/**
@param sharedPreferenceName shared pref name used to save salt
@param pbkdf2IterationCount number of iteration used for encryption
@param isSerialIncludedInDevicePackageSpecificId
Indicates if we should also include Build.Serial as an identifier to generate
the device Id.
Note : This field should always be false as it is deprecated and
returns UNKNOWN in some cases from Android SDK >= 27
*/
public StringCipher(
@NonNull String sharedPreferenceName,
int pbkdf2IterationCount,
boolean isSerialIncludedInDevicePackageSpecificId) {
this.sharedPreferenceName = sharedPreferenceName;
this.pbkdf2IterationCount = pbkdf2IterationCount;
this.isSerialIncludedInDevicePackageSpecificId = isSerialIncludedInDevicePackageSpecificId;
// should be available on all Android 15+ devices
// hard fail if not so
try {
secureRandom = new SecureRandom();
keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
hmac = Mac.getInstance("HmacSHA256");
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
throw new RuntimeException(e);
}
}
/**
* Generates a random number using two UUIDs and HMAC-SHA1
*
* @return generated secure random number
* @throws IdentityOAuthAdminException Invalid Algorithm or Invalid Key
*/
public static String getRandomNumber() throws IdentityOAuthAdminException {
try {
String secretKey = UUIDGenerator.generateUUID();
String baseString = UUIDGenerator.generateUUID();
SecretKeySpec key = new SecretKeySpec(secretKey.getBytes(Charsets.UTF_8), ALGORITHM);
Mac mac = Mac.getInstance(ALGORITHM);
mac.init(key);
byte[] rawHmac = mac.doFinal(baseString.getBytes(Charsets.UTF_8));
String random = Base64.encode(rawHmac);
// Registry doesn't have support for these character.
random = random.replace("/", "_");
random = random.replace("=", "a");
random = random.replace("+", "f");
return random;
} catch (Exception e) {
throw new IdentityOAuthAdminException("Error when generating a random number.", e);
}
}
@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);
try {
ByteBuffer buf = null;
mac.update(buf);
mac.doFinal();
throw new RuntimeException(
"Expected IllegalArgumentException not thrown");
} catch (IllegalArgumentException e) {
System.out.println("Expected IllegalArgumentException thrown: "
+ e);
}
}
@Override
public Identity decode(final byte[] bytes) throws IOException {
final Mac mac = this.mac();
if (bytes.length < mac.getMacLength()) {
throw new IOException("Invalid data size");
}
final byte[] signature = new byte[mac.getMacLength()];
final byte[] encoded = new byte[bytes.length - signature.length];
System.arraycopy(bytes, 0, encoded, 0, encoded.length);
System.arraycopy(
bytes,
encoded.length,
signature,
0,
signature.length
);
final byte[] actual = mac.doFinal(encoded);
if (!Arrays.equals(actual, signature)) {
throw new IOException("Bad signature");
}
return this.cdc.decode(encoded);
}
/**
* 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;
}
/**
* Derives an array of bytes from a source and a secret key.
*
* @param source The source.
* @param length The length of the derived array of bytes.
* @return The derived array of bytes.
*/
public byte[] derive(
String source,
int length) {
byte[] key = derivationKeys.get(length);
if (key == null) {
throw new ServiceException(String.format("No key of length %s was defined", length));
}
try {
String algorithm = "HmacSHA" + length * 8;
Mac mac = Mac.getInstance(algorithm);
SecretKeySpec keySpec = new SecretKeySpec(key, algorithm);
mac.init(keySpec);
return mac.doFinal(source.getBytes(StandardCharsets.UTF_8));
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
throw new ServiceException("Error during the derivation process", e);
}
}
/**
* Get the truncated HMAC
*/
protected byte[] getHmac(byte[] key, byte[] msg)
throws GeneralSecurityException {
SecretKey keyKi = new SecretKeySpec(key, "HMAC");
Mac m = Mac.getInstance("HmacSHA1");
m.init(keyKi);
// generate hash
byte[] hash = m.doFinal(msg);
// truncate hash
byte[] output = new byte[hashSize];
System.arraycopy(hash, 0, output, 0, hashSize);
return output;
}
public MacSyslogMessageModifier(MacSyslogMessageModifierConfig config) throws SyslogRuntimeException {
super(config);
this.config = config;
try {
this.mac = Mac.getInstance(config.getMacAlgorithm());
this.mac.init(config.getKey());
} catch (NoSuchAlgorithmException nsae) {
throw new SyslogRuntimeException(nsae);
} catch (InvalidKeyException ike) {
throw new SyslogRuntimeException(ike);
}
}
private void sendVote(Vote vote, Key key, boolean expectSuccess) throws Exception {
// Create a well-formed request
EmbeddedChannel channel = createChannel();
JSONObject object = new JSONObject();
JsonObject payload = vote.serialize();
payload.addProperty("challenge", SESSION.getChallenge());
String payloadEncoded = GsonInst.gson.toJson(payload);
object.put("payload", payloadEncoded);
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(key);
object.put("signature",
Base64.getEncoder().encodeToString(mac.doFinal(payloadEncoded.getBytes(StandardCharsets.UTF_8))));
if (expectSuccess) {
assertTrue(channel.writeInbound(object.toString()));
assertEquals(vote, channel.readInbound());
assertFalse(channel.finish());
} else {
try {
channel.writeInbound(object.toString());
} finally {
channel.close();
}
}
}
/**
* 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;
}
public static byte[] computeIdentityKey(byte[] sharedSecret, byte[] serverPublicKey,
byte[] beaconPublicKey) throws InvalidKeyException, NoSuchAlgorithmException {
if (Util.isZeroBuffer(sharedSecret)) {
throw new InvalidKeyException("Shared secret is zero");
}
byte[] salt = new byte[serverPublicKey.length + beaconPublicKey.length];
System.arraycopy(serverPublicKey, 0, salt, 0, serverPublicKey.length);
System.arraycopy(beaconPublicKey, 0, salt, serverPublicKey.length, beaconPublicKey.length);
Mac mac = Mac.getInstance("hmacSHA256");
// hkdf extract
mac.init(new SecretKeySpec(salt, "hmacSHA256"));
byte[] pseudoRandomKey = mac.doFinal(sharedSecret);
// hkdf expand
mac.reset();
mac.init(new SecretKeySpec(pseudoRandomKey, "hmacSHA256"));
return mac.doFinal(new byte[]{1});
}
@Nullable
public String encrypt(@NonNull BiometricPrompt.CryptoObject cryptoObject, @NonNull String value) {
Cipher cipher = cryptoObject.getCipher();
if (cipher != null && cipherCrypter != null) {
return cipherCrypter.encrypt(cipher, value);
}
Mac mac = cryptoObject.getMac();
if (mac != null && macCrypter != null) {
return macCrypter.encrypt(mac, value);
}
Signature signature = cryptoObject.getSignature();
if (signature != null && signatureCrypter != null) {
return signatureCrypter.encrypt(signature, value);
}
return null;
}
private byte[] verifyMacBody(@NonNull Mac hmac, @NonNull byte[] encryptedAndMac) throws InvalidMessageException {
if (encryptedAndMac.length < hmac.getMacLength()) {
throw new InvalidMessageException("length(encrypted body + MAC) < length(MAC)");
}
byte[] encrypted = new byte[encryptedAndMac.length - hmac.getMacLength()];
System.arraycopy(encryptedAndMac, 0, encrypted, 0, encrypted.length);
byte[] remoteMac = new byte[hmac.getMacLength()];
System.arraycopy(encryptedAndMac, encryptedAndMac.length - remoteMac.length, remoteMac, 0, remoteMac.length);
byte[] localMac = hmac.doFinal(encrypted);
if (!Arrays.equals(remoteMac, localMac))
throw new InvalidMessageException("MAC doesen't match.");
return encrypted;
}
private static int verify_code(byte[] key, long t) throws NoSuchAlgorithmException, InvalidKeyException {
byte[] data = new byte[8];
long value = t;
for (int i = 8; i-- > 0; value >>>= 8) {
data[i] = (byte) value;
}
SecretKeySpec signKey = new SecretKeySpec(key, "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(signKey);
byte[] hash = mac.doFinal(data);
int offset = hash[20 - 1] & 0xF;
// We're using a long because Java hasn't got unsigned int.
long truncatedHash = 0;
for (int i = 0; i < 4; ++i) {
truncatedHash <<= 8;
// We are dealing with signed bytes:
// we just keep the first byte.
truncatedHash |= (hash[offset + i] & 0xFF);
}
truncatedHash &= 0x7FFFFFFF;
truncatedHash %= 1000000;
return (int) truncatedHash;
}
public static byte[] sign(String toSign, String secret) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, UnsupportedEncodingException {
validateParameters(toSign, secret);
String password = secret;
PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
SecretKeyFactory kf = SecretKeyFactory
.getInstance("PBEWithMD5AndDES");
SecretKey passwordKey = kf.generateSecret(keySpec);
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(passwordKey);
byte[] text = toSign.getBytes("UTF-8");
byte[] signatureBytes = mac.doFinal(text);
return signatureBytes;
}
/**
* Method IntegrityHmac
*
* @throws XMLSignatureException
*/
public IntegrityHmac() throws XMLSignatureException {
String algorithmID = JCEMapper.translateURItoJCEID(this.engineGetURI());
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, "Created IntegrityHmacSHA1 using " + algorithmID);
}
try {
this.macAlgorithm = Mac.getInstance(algorithmID);
} catch (java.security.NoSuchAlgorithmException ex) {
Object[] exArgs = { algorithmID, ex.getLocalizedMessage() };
throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs);
}
}
/**
* Proxy method for {@link java.security.Signature#initVerify(java.security.PublicKey)}
* which is executed on the internal {@link java.security.Signature} object.
*
* @param secretKey
* @throws XMLSignatureException
*/
protected void engineInitVerify(Key secretKey) throws XMLSignatureException {
if (!(secretKey instanceof SecretKey)) {
String supplied = secretKey.getClass().getName();
String needed = SecretKey.class.getName();
Object exArgs[] = { supplied, needed };
throw new XMLSignatureException("algorithms.WrongKeyForThisOperation", exArgs);
}
try {
this.macAlgorithm.init(secretKey);
} catch (InvalidKeyException ex) {
// reinstantiate Mac object to work around bug in JDK
// see: http://bugs.sun.com/view_bug.do?bug_id=4953555
Mac mac = this.macAlgorithm;
try {
this.macAlgorithm = Mac.getInstance(macAlgorithm.getAlgorithm());
} catch (Exception e) {
// this shouldn't occur, but if it does, restore previous Mac
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, "Exception when reinstantiating Mac:" + e);
}
this.macAlgorithm = mac;
}
throw new XMLSignatureException("empty", ex);
}
}
private static String calculateHMAC(String secret, String data) {
try {
SecretKeySpec signingKey = new SecretKeySpec(DatatypeConverter.parseHexBinary(secret), "HmacSHA256");
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(signingKey);
byte[] rawHmac = mac.doFinal(data.getBytes());
return Base64.getEncoder().encodeToString(rawHmac);
} catch (NoSuchAlgorithmException | InvalidKeyException | IllegalStateException ex) {
WebauthnTutorialLogger.logp(Level.SEVERE, CLASSNAME, "calculateHMAC",
"WEBAUTHN-ERR-5000", ex.getLocalizedMessage());
throw new WebServiceException(WebauthnTutorialLogger.getMessageProperty("WEBAUTHN-ERR-5000"));
}
}
private void verifyMac(byte[] ciphertext, SecretKeySpec macKey) throws IOException {
try {
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(macKey);
if (ciphertext.length < MAC_SIZE + 1)
throw new IOException("Invalid MAC!");
mac.update(ciphertext, 0, ciphertext.length - MAC_SIZE);
byte[] ourMacFull = mac.doFinal();
byte[] ourMacBytes = new byte[MAC_SIZE];
System.arraycopy(ourMacFull, 0, ourMacBytes, 0, ourMacBytes.length);
byte[] theirMacBytes = new byte[MAC_SIZE];
System.arraycopy(ciphertext, ciphertext.length-MAC_SIZE, theirMacBytes, 0, theirMacBytes.length);
Log.w(TAG, "Our MAC: " + Hex.toString(ourMacBytes));
Log.w(TAG, "Thr MAC: " + Hex.toString(theirMacBytes));
if (!Arrays.equals(ourMacBytes, theirMacBytes)) {
throw new IOException("Invalid MAC compare!");
}
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
throw new AssertionError(e);
}
}
/**
* @see #isUrlValid
*
* @param url A URL for which to calculate a MAC.
*
* @return The bytes of a MAC for the URL, or null if a secure MAC was not available.
*/
public static byte[] getMacForUrl(Context context, String url) {
Mac mac = getMac(context);
if (mac == null) {
return null;
}
return mac.doFinal(url.getBytes());
}
/**
* 生成HMAC摘要
*
* @param algorithm 算法
* @param plaintext 明文
* @param appKey 秘钥
*/
public static String hmacDigest(String algorithm, String plaintext, String secretKey) {
try {
Mac mac = Mac.getInstance(algorithm);
byte[] secretByte = secretKey.getBytes();
byte[] dataBytes = plaintext.getBytes();
SecretKey secret = new SecretKeySpec(secretByte, algorithm);
mac.init(secret);
byte[] doFinal = mac.doFinal(dataBytes);
return CommonUtils.byte2HexStr(doFinal);
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}
protected byte[] signWithMac(String stringData, Mac mac) {
try {
return mac.doFinal(stringData.getBytes(StandardCharsets.UTF_8));
} catch (Exception e) {
throw SdkClientException.builder()
.message("Unable to calculate a request signature: " + e.getMessage())
.cause(e)
.build();
}
}
boolean verify(Key key, SignedInfo si, byte[] sig,
XMLValidateContext context)
throws InvalidKeyException, SignatureException, XMLSignatureException
{
if (key == null || si == null || sig == null) {
throw new NullPointerException();
}
if (!(key instanceof SecretKey)) {
throw new InvalidKeyException("key must be SecretKey");
}
if (hmac == null) {
try {
hmac = Mac.getInstance(getJCAAlgorithm());
} catch (NoSuchAlgorithmException nsae) {
throw new XMLSignatureException(nsae);
}
}
if (outputLengthSet && outputLength < getDigestLength()) {
throw new XMLSignatureException
("HMACOutputLength must not be less than " + getDigestLength());
}
hmac.init((SecretKey)key);
((DOMSignedInfo)si).canonicalize(context, new MacOutputStream(hmac));
byte[] result = hmac.doFinal();
return MessageDigest.isEqual(sig, result);
}
/**
* Method IntegrityHmac
*
* @throws XMLSignatureException
*/
public IntegrityHmac() throws XMLSignatureException {
String algorithmID = JCEMapper.translateURItoJCEID(this.engineGetURI());
if (log.isLoggable(java.util.logging.Level.FINE)) {
log.log(java.util.logging.Level.FINE, "Created IntegrityHmacSHA1 using " + algorithmID);
}
try {
this.macAlgorithm = Mac.getInstance(algorithmID);
} catch (java.security.NoSuchAlgorithmException ex) {
Object[] exArgs = { algorithmID, ex.getLocalizedMessage() };
throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs);
}
}
private void makeMasterKey()
throws NoSuchAlgorithmException, InvalidKeyException {
SecretKeySpec keySpec = new SecretKeySpec(
NKFDbytes("Bitcoin seed"),
"HmacSHA512");
Mac mac = Mac.getInstance("HmacSHA512");
mac.init(keySpec);
byte[] result = mac.doFinal(seed);
mkey = Arrays.copyOfRange(result, 0, 32);
mchain = Arrays.copyOfRange(result, 32, 64);
}
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);
}
}
protected Observable<Optional<byte[]>> decryptPrimary0(VertxContext<Server> vertxContext, PersistentMasterKey persistentMasterKey, boolean validate) {
return defer(() -> {
Optional<byte[]> oEncryptedKey = persistentMasterKey.getEncryptedKey();
Optional<String> oKeyId = persistentMasterKey.getKeyId();
if (oKeyId.isPresent() && oEncryptedKey.isPresent()) {
byte[] encryptedKey = oEncryptedKey.get();
Kms kms = fromKeyId(vertxContext, oKeyId.get());
return kms.decrypt(vertxContext, encryptedKey)
.map(plainBytes -> {
if (validate) {
Optional<byte[]> oSecretSalt = persistentMasterKey.getSecretSalt();
Optional<byte[]> oSecretSha512 = persistentMasterKey.getSecretSha512();
if (oSecretSalt.isPresent() && oSecretSha512.isPresent()) {
byte[] secretSalt = oSecretSalt.get();
byte[] expectedSecretSha512 = oSecretSha512.get();
Mac mac = SHA512.instance(secretSalt);
byte[] computedSecretSha512 = mac.doFinal(plainBytes);
if (!Arrays.equals(expectedSecretSha512, computedSecretSha512)) {
throw new KeyDigestMismatchException("Computed key digest didn't match expected key digest");
}
return plainBytes;
}
}
return plainBytes;
})
.map(Optional::of);
} else {
return just(Optional.<byte[]>absent());
}
});
}
public static String computeHmacSHA1AsHexUpperCase(String key, String text) {
try {
Mac mac = Mac.getInstance("HmacSHA1");
SecretKeySpec secret = new SecretKeySpec(key.getBytes(), "HmacSHA1");
mac.init(secret);
byte[] digest = mac.doFinal(text.getBytes());
return convertByte2HexUpperCase(digest);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("The JVM does algorithm - maybe it's not correct JVM version", e);
} catch (InvalidKeyException ike) {
throw new RuntimeException(
"InvalidKeyException: " + ike + ", maybe the JVM version is not correct", ike);
}
}
boolean verify(Key key, SignedInfo si, byte[] sig,
XMLValidateContext context)
throws InvalidKeyException, SignatureException, XMLSignatureException
{
if (key == null || si == null || sig == null) {
throw new NullPointerException();
}
if (!(key instanceof SecretKey)) {
throw new InvalidKeyException("key must be SecretKey");
}
if (hmac == null) {
try {
hmac = Mac.getInstance(getJCAAlgorithm());
} catch (NoSuchAlgorithmException nsae) {
throw new XMLSignatureException(nsae);
}
}
if (outputLengthSet && outputLength < getDigestLength()) {
throw new XMLSignatureException
("HMACOutputLength must not be less than " + getDigestLength());
}
hmac.init((SecretKey)key);
((DOMSignedInfo)si).canonicalize(context, new MacOutputStream(hmac));
byte[] result = hmac.doFinal();
return MessageDigest.isEqual(sig, result);
}