mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 722430 - Propagate NoSuchAlgorithmException and InvalidKeyException; wrap in CryptoException higher up the call stack. r=rnewman
This commit is contained in:
parent
0cca0b16db
commit
91bb310434
@ -1,102 +1,66 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Android Sync Client.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* the Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jason Voll
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.gecko.sync.crypto;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* All info in these objects should be decoded (i.e. not BaseXX encoded).
|
||||
*/
|
||||
public class CryptoInfo {
|
||||
|
||||
private byte[] message;
|
||||
private byte[] iv;
|
||||
private byte[] hmac;
|
||||
private KeyBundle keys;
|
||||
private byte[] message;
|
||||
private byte[] iv;
|
||||
private byte[] hmac;
|
||||
private KeyBundle keys;
|
||||
|
||||
/*
|
||||
* Constructor typically used when encrypting
|
||||
*/
|
||||
public CryptoInfo(byte[] message, KeyBundle keys) {
|
||||
this.setMessage(message);
|
||||
this.setKeys(keys);
|
||||
}
|
||||
/*
|
||||
* Constructor typically used when encrypting.
|
||||
*/
|
||||
public CryptoInfo(byte[] message, KeyBundle keys) {
|
||||
this.setMessage(message);
|
||||
this.setKeys(keys);
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor typically used when decrypting
|
||||
*/
|
||||
public CryptoInfo(byte[] message, byte[] iv, byte[] hmac, KeyBundle keys) {
|
||||
this.setMessage(message);
|
||||
this.setIV(iv);
|
||||
this.setHMAC(hmac);
|
||||
this.setKeys(keys);
|
||||
}
|
||||
/*
|
||||
* Constructor typically used when decrypting.
|
||||
*/
|
||||
public CryptoInfo(byte[] message, byte[] iv, byte[] hmac, KeyBundle keys) {
|
||||
this.setMessage(message);
|
||||
this.setIV(iv);
|
||||
this.setHMAC(hmac);
|
||||
this.setKeys(keys);
|
||||
}
|
||||
|
||||
public byte[] getMessage() {
|
||||
return message;
|
||||
}
|
||||
public byte[] getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(byte[] message) {
|
||||
this.message = message;
|
||||
}
|
||||
public void setMessage(byte[] message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public byte[] getIV() {
|
||||
return iv;
|
||||
}
|
||||
public byte[] getIV() {
|
||||
return iv;
|
||||
}
|
||||
|
||||
public void setIV(byte[] iv) {
|
||||
this.iv = iv;
|
||||
}
|
||||
public void setIV(byte[] iv) {
|
||||
this.iv = iv;
|
||||
}
|
||||
|
||||
public byte[] getHMAC() {
|
||||
return hmac;
|
||||
}
|
||||
public byte[] getHMAC() {
|
||||
return hmac;
|
||||
}
|
||||
|
||||
public void setHMAC(byte[] hmac) {
|
||||
this.hmac = hmac;
|
||||
}
|
||||
public void setHMAC(byte[] hmac) {
|
||||
this.hmac = hmac;
|
||||
}
|
||||
|
||||
public KeyBundle getKeys() {
|
||||
return keys;
|
||||
}
|
||||
|
||||
public void setKeys(KeyBundle keys) {
|
||||
this.keys = keys;
|
||||
}
|
||||
public KeyBundle getKeys() {
|
||||
return keys;
|
||||
}
|
||||
|
||||
public void setKeys(KeyBundle keys) {
|
||||
this.keys = keys;
|
||||
}
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ import javax.crypto.spec.SecretKeySpec;
|
||||
import org.mozilla.apache.commons.codec.binary.Base32;
|
||||
import org.mozilla.apache.commons.codec.binary.Base64;
|
||||
import org.mozilla.gecko.sync.Utils;
|
||||
import java.security.InvalidKeyException;
|
||||
|
||||
/*
|
||||
* Implements the basic required cryptography options.
|
||||
@ -82,7 +83,6 @@ public class Cryptographer {
|
||||
cipher.init(Cipher.ENCRYPT_MODE, spec, new IvParameterSpec(info.getIV()));
|
||||
}
|
||||
} catch (GeneralSecurityException ex) {
|
||||
ex.printStackTrace();
|
||||
throw new CryptoException(ex);
|
||||
}
|
||||
|
||||
@ -94,7 +94,13 @@ public class Cryptographer {
|
||||
info.setIV(cipher.getIV());
|
||||
|
||||
// Generate HMAC.
|
||||
info.setHMAC(generateHMAC(info));
|
||||
try {
|
||||
info.setHMAC(generateHMAC(info));
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new CryptoException(e);
|
||||
} catch (InvalidKeyException e) {
|
||||
throw new CryptoException(e);
|
||||
}
|
||||
|
||||
return info;
|
||||
|
||||
@ -112,8 +118,14 @@ public class Cryptographer {
|
||||
public static byte[] decrypt(CryptoInfo info) throws CryptoException {
|
||||
|
||||
// Check HMAC.
|
||||
if (!verifyHMAC(info)) {
|
||||
throw new HMACVerificationException();
|
||||
try {
|
||||
if (!verifyHMAC(info)) {
|
||||
throw new HMACVerificationException();
|
||||
}
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new CryptoException(e);
|
||||
} catch (InvalidKeyException e) {
|
||||
throw new CryptoException(e);
|
||||
}
|
||||
|
||||
Cipher cipher = getCipher();
|
||||
@ -190,7 +202,7 @@ public class Cryptographer {
|
||||
/*
|
||||
* Helper to verify HMAC Input: CryptoInfo Output: true if HMAC is correct
|
||||
*/
|
||||
private static boolean verifyHMAC(CryptoInfo bundle) {
|
||||
private static boolean verifyHMAC(CryptoInfo bundle) throws NoSuchAlgorithmException, InvalidKeyException {
|
||||
byte[] generatedHMAC = generateHMAC(bundle);
|
||||
byte[] expectedHMAC = bundle.getHMAC();
|
||||
boolean eq = Arrays.equals(generatedHMAC, expectedHMAC);
|
||||
@ -206,7 +218,7 @@ public class Cryptographer {
|
||||
* Helper to generate HMAC Input: CryptoInfo Output: a generated HMAC for
|
||||
* given cipher text
|
||||
*/
|
||||
private static byte[] generateHMAC(CryptoInfo bundle) {
|
||||
private static byte[] generateHMAC(CryptoInfo bundle) throws NoSuchAlgorithmException, InvalidKeyException {
|
||||
Mac hmacHasher = HKDF.makeHMACHasher(bundle.getKeys().getHMACKey());
|
||||
return hmacHasher.doFinal(Base64.encodeBase64(bundle.getMessage()));
|
||||
}
|
||||
|
@ -1,39 +1,6 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Android Sync Client.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* the Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jason Voll
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.gecko.sync.crypto;
|
||||
|
||||
@ -46,105 +13,99 @@ import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
import org.mozilla.gecko.sync.Utils;
|
||||
|
||||
|
||||
/*
|
||||
* A standards-compliant implementation of RFC 5869
|
||||
* for HMAC-based Key Derivation Function.
|
||||
* HMAC uses HMAC SHA256 standard.
|
||||
*/
|
||||
public class HKDF {
|
||||
public static String HMAC_ALGORITHM = "hmacSHA256";
|
||||
|
||||
/**
|
||||
* Used for conversion in cases in which you *know* the encoding exists.
|
||||
*/
|
||||
public static final byte[] bytes(String in) {
|
||||
try {
|
||||
return in.getBytes("UTF-8");
|
||||
} catch (java.io.UnsupportedEncodingException e) {
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Used for conversion in cases in which you *know* the encoding exists.
|
||||
*/
|
||||
public static final byte[] bytes(String in) {
|
||||
try {
|
||||
return in.getBytes("UTF-8");
|
||||
} catch (java.io.UnsupportedEncodingException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static final int BLOCKSIZE = 256 / 8;
|
||||
public static final byte[] HMAC_INPUT = bytes("Sync-AES_256_CBC-HMAC256");
|
||||
|
||||
/*
|
||||
* Step 1 of RFC 5869
|
||||
* Get sha256HMAC Bytes
|
||||
* Input: salt (message), IKM (input keyring material)
|
||||
* Output: PRK (pseudorandom key)
|
||||
*/
|
||||
public static byte[] hkdfExtract(byte[] salt, byte[] IKM) throws NoSuchAlgorithmException, InvalidKeyException {
|
||||
return digestBytes(IKM, makeHMACHasher(salt));
|
||||
}
|
||||
|
||||
/*
|
||||
* Step 2 of RFC 5869.
|
||||
* Input: PRK from step 1, info, length.
|
||||
* Output: OKM (output keyring material).
|
||||
*/
|
||||
public static byte[] hkdfExpand(byte[] prk, byte[] info, int len) throws NoSuchAlgorithmException, InvalidKeyException {
|
||||
Mac hmacHasher = makeHMACHasher(prk);
|
||||
|
||||
byte[] T = {};
|
||||
byte[] Tn = {};
|
||||
|
||||
int iterations = (int) Math.ceil(((double)len) / ((double)BLOCKSIZE));
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
Tn = digestBytes(Utils.concatAll(Tn, info, Utils.hex2Byte(Integer.toHexString(i + 1))),
|
||||
hmacHasher);
|
||||
T = Utils.concatAll(T, Tn);
|
||||
}
|
||||
|
||||
public static final int BLOCKSIZE = 256 / 8;
|
||||
public static final byte[] HMAC_INPUT = bytes("Sync-AES_256_CBC-HMAC256");
|
||||
byte[] result = new byte[len];
|
||||
System.arraycopy(T, 0, result, 0, len);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Step 1 of RFC 5869
|
||||
* Get sha256HMAC Bytes
|
||||
* Input: salt (message), IKM (input keyring material)
|
||||
* Output: PRK (pseudorandom key)
|
||||
*/
|
||||
public static byte[] hkdfExtract(byte[] salt, byte[] IKM) {
|
||||
return digestBytes(IKM, makeHMACHasher(salt));
|
||||
/*
|
||||
* Make HMAC key
|
||||
* Input: key (salt)
|
||||
* Output: Key HMAC-Key
|
||||
*/
|
||||
public static Key makeHMACKey(byte[] key) {
|
||||
if (key.length == 0) {
|
||||
key = new byte[BLOCKSIZE];
|
||||
}
|
||||
return new SecretKeySpec(key, HMAC_ALGORITHM);
|
||||
}
|
||||
|
||||
/*
|
||||
* Step 2 of RFC 5869.
|
||||
* Input: PRK from step 1, info, length.
|
||||
* Output: OKM (output keyring material).
|
||||
*/
|
||||
public static byte[] hkdfExpand(byte[] prk, byte[] info, int len) {
|
||||
/*
|
||||
* Make an HMAC hasher
|
||||
* Input: Key hmacKey
|
||||
* Ouput: An HMAC Hasher
|
||||
*/
|
||||
public static Mac makeHMACHasher(byte[] key) throws NoSuchAlgorithmException, InvalidKeyException {
|
||||
Mac hmacHasher = null;
|
||||
hmacHasher = Mac.getInstance(HMAC_ALGORITHM);
|
||||
|
||||
Mac hmacHasher = makeHMACHasher(prk);
|
||||
// If Mac.getInstance doesn't throw NoSuchAlgorithmException, hmacHasher is
|
||||
// non-null.
|
||||
assert(hmacHasher != null);
|
||||
|
||||
byte[] T = {};
|
||||
byte[] Tn = {};
|
||||
hmacHasher.init(makeHMACKey(key));
|
||||
return hmacHasher;
|
||||
}
|
||||
|
||||
int iterations = (int) Math.ceil(((double)len) / ((double)BLOCKSIZE));
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
Tn = digestBytes(Utils.concatAll
|
||||
(Tn, info, Utils.hex2Byte(Integer.toHexString(i + 1))), hmacHasher);
|
||||
T = Utils.concatAll(T, Tn);
|
||||
}
|
||||
|
||||
byte[] result = new byte[len];
|
||||
System.arraycopy(T, 0, result, 0, len);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make HMAC key
|
||||
* Input: key (salt)
|
||||
* Output: Key HMAC-Key
|
||||
*/
|
||||
public static Key makeHMACKey(byte[] key) {
|
||||
if (key.length == 0) {
|
||||
key = new byte[BLOCKSIZE];
|
||||
}
|
||||
return new SecretKeySpec(key, "HmacSHA256");
|
||||
}
|
||||
|
||||
/*
|
||||
* Make an HMAC hasher
|
||||
* Input: Key hmacKey
|
||||
* Ouput: An HMAC Hasher
|
||||
*/
|
||||
public static Mac makeHMACHasher(byte[] key) {
|
||||
Mac hmacHasher = null;
|
||||
try {
|
||||
hmacHasher = Mac.getInstance("hmacSHA256");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
hmacHasher.init(makeHMACKey(key));
|
||||
} catch (InvalidKeyException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return hmacHasher;
|
||||
}
|
||||
|
||||
/*
|
||||
* Hash bytes with given hasher
|
||||
* Input: message to hash, HMAC hasher
|
||||
* Output: hashed byte[].
|
||||
*/
|
||||
public static byte[] digestBytes(byte[] message, Mac hasher) {
|
||||
hasher.update(message);
|
||||
byte[] ret = hasher.doFinal();
|
||||
hasher.reset();
|
||||
return ret;
|
||||
}
|
||||
/*
|
||||
* Hash bytes with given hasher
|
||||
* Input: message to hash, HMAC hasher
|
||||
* Output: hashed byte[].
|
||||
*/
|
||||
public static byte[] digestBytes(byte[] message, Mac hasher) {
|
||||
hasher.update(message);
|
||||
byte[] ret = hasher.doFinal();
|
||||
hasher.reset();
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
@ -45,6 +45,8 @@ import javax.crypto.Mac;
|
||||
|
||||
import org.mozilla.apache.commons.codec.binary.Base64;
|
||||
import org.mozilla.gecko.sync.Utils;
|
||||
import org.mozilla.gecko.sync.crypto.CryptoException;
|
||||
import java.security.InvalidKeyException;
|
||||
|
||||
public class KeyBundle {
|
||||
|
||||
@ -86,7 +88,7 @@ public class KeyBundle {
|
||||
* encryption key and the second iteration the HMAC key.
|
||||
*
|
||||
*/
|
||||
public KeyBundle(String username, String base32SyncKey) {
|
||||
public KeyBundle(String username, String base32SyncKey) throws CryptoException {
|
||||
if (base32SyncKey == null) {
|
||||
throw new IllegalArgumentException("No sync key provided.");
|
||||
}
|
||||
@ -105,7 +107,15 @@ public class KeyBundle {
|
||||
byte[] syncKey = Utils.decodeFriendlyBase32(base32SyncKey);
|
||||
byte[] user = username.getBytes();
|
||||
|
||||
Mac hmacHasher = HKDF.makeHMACHasher(syncKey);
|
||||
Mac hmacHasher;
|
||||
try {
|
||||
hmacHasher = HKDF.makeHMACHasher(syncKey);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new CryptoException(e);
|
||||
} catch (InvalidKeyException e) {
|
||||
throw new CryptoException(e);
|
||||
}
|
||||
assert(hmacHasher != null); // If makeHMACHasher doesn't throw, then hmacHasher is non-null.
|
||||
|
||||
byte[] encrBytes = Utils.concatAll(EMPTY_BYTES, HKDF.HMAC_INPUT, user, ENCR_INPUT_BYTES);
|
||||
byte[] encrKey = HKDF.digestBytes(encrBytes, hmacHasher);
|
||||
|
@ -344,7 +344,7 @@ public class SyncCryptographer {
|
||||
/*
|
||||
* Get the keys needed to encrypt the crypto/keys bundle.
|
||||
*/
|
||||
public KeyBundle getCryptoKeysBundleKeys() {
|
||||
public KeyBundle getCryptoKeysBundleKeys() throws CryptoException {
|
||||
return new KeyBundle(username, syncKey);
|
||||
}
|
||||
|
||||
|
@ -74,6 +74,8 @@ import ch.boye.httpclientandroidlib.client.methods.HttpRequestBase;
|
||||
import ch.boye.httpclientandroidlib.entity.StringEntity;
|
||||
import ch.boye.httpclientandroidlib.impl.client.DefaultHttpClient;
|
||||
import ch.boye.httpclientandroidlib.message.BasicHeader;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.InvalidKeyException;
|
||||
|
||||
public class JPakeClient implements JPakeRequestDelegate {
|
||||
private static String LOG_TAG = "JPakeClient";
|
||||
@ -474,6 +476,14 @@ public class JPakeClient implements JPakeRequestDelegate {
|
||||
Log.e(LOG_TAG, "ZKP mismatch");
|
||||
abort(Constants.JPAKE_ERROR_WRONGMESSAGE);
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
Log.e(LOG_TAG, "NoSuchAlgorithmException", e);
|
||||
abort(Constants.JPAKE_ERROR_INTERNAL);
|
||||
e.printStackTrace();
|
||||
} catch (InvalidKeyException e) {
|
||||
Log.e(LOG_TAG, "InvalidKeyException", e);
|
||||
abort(Constants.JPAKE_ERROR_INTERNAL);
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (pairWithPin) { // Wait for other device to send verification of keys.
|
||||
|
@ -51,6 +51,7 @@ import org.mozilla.gecko.sync.crypto.HKDF;
|
||||
import org.mozilla.gecko.sync.crypto.KeyBundle;
|
||||
|
||||
import android.util.Log;
|
||||
import java.security.InvalidKeyException;
|
||||
|
||||
public class JPakeCrypto {
|
||||
private static final String LOG_TAG = "JPakeCrypto";
|
||||
@ -174,7 +175,7 @@ public class JPakeCrypto {
|
||||
* @throws IncorrectZkpException
|
||||
*/
|
||||
public static KeyBundle finalRound(String secret, JPakeParty jp)
|
||||
throws IncorrectZkpException {
|
||||
throws IncorrectZkpException, NoSuchAlgorithmException, InvalidKeyException {
|
||||
Log.d(LOG_TAG, "Final round started.");
|
||||
BigInteger gb = jp.gx1.multiply(jp.gx2).mod(P).multiply(jp.gx3)
|
||||
.mod(P);
|
||||
@ -321,12 +322,12 @@ public class JPakeCrypto {
|
||||
/*
|
||||
* Helper function to generate encryption key and HMAC from a byte array.
|
||||
*/
|
||||
public static void generateKeyAndHmac(BigInteger k, byte[] encOut, byte[] hmacOut) {
|
||||
public static void generateKeyAndHmac(BigInteger k, byte[] encOut, byte[] hmacOut) throws NoSuchAlgorithmException, InvalidKeyException {
|
||||
// Generate HMAC and Encryption keys from synckey.
|
||||
byte[] zerokey = new byte[32];
|
||||
byte[] prk = HMACSHA256(BigIntegerHelper.BigIntegerToByteArrayWithoutSign(k), zerokey);
|
||||
|
||||
byte[] okm = HKDF.hkdfExpand(prk, HKDF.HMAC_INPUT, 32 * 2);
|
||||
byte[] okm = HKDF.hkdfExpand(prk, HKDF.HMAC_INPUT, 32 * 2);
|
||||
System.arraycopy(okm, 0, encOut, 0, 32);
|
||||
System.arraycopy(okm, 32, hmacOut, 0, 32);
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ public class BaseResource implements Resource {
|
||||
}
|
||||
|
||||
public BaseResource(String uri, boolean rewrite) throws URISyntaxException {
|
||||
this(new URI(uri), rewrite);
|
||||
this(new URI(uri), rewrite);
|
||||
}
|
||||
|
||||
public BaseResource(URI uri, boolean rewrite) {
|
||||
|
Loading…
Reference in New Issue
Block a user