I am trying to access my encrypt key stored in application.properties and set it as SECRET property in my AttributeEncryptor.
This is the class:
package com.nimesia.sweetvillas.encryptors;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.spec.SecretKeySpec;
import javax.persistence.AttributeConverter;
import java.security.InvalidKeyException;
import java.security.Key;
import java.util.Base64;
#Component
public class AttributeEncryptor implements AttributeConverter<String, String> {
private static final String AES = "AES";
#Value("${datasource.encryptkey}")
private String SECRET;
private final Key key;
private final Cipher cipher;
public AttributeEncryptor() throws Exception {
key = new SecretKeySpec(SECRET.getBytes(), AES);
cipher = Cipher.getInstance(AES);
}
#Override
public String convertToDatabaseColumn(String attribute) {
try {
cipher.init(Cipher.ENCRYPT_MODE, key);
return Base64.getEncoder().encodeToString(cipher.doFinal(attribute.getBytes()));
} catch (IllegalBlockSizeException | BadPaddingException | InvalidKeyException e) {
throw new IllegalStateException(e);
}
}
#Override
public String convertToEntityAttribute(String dbData) {
try {
cipher.init(Cipher.DECRYPT_MODE, key);
return new String(cipher.doFinal(Base64.getDecoder().decode(dbData)));
} catch (InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) {
throw new IllegalStateException(e);
}
}
}
datasource.encryptkey is in application.properties.
I have tried to access it from a controller and it worked. But when I try and use it in here it gives me a NullPointerException.
Hope I was clear.
Thanks in advance
The class is created before the property is set!
You should add it to the constructor instead:
private final String SECRET;
private final Key key;
private final Cipher cipher;
public AttributeEncryptor(#Value("${datasource.encryptkey}") String secret) throws Exception {
SECRET = secret;
key = new SecretKeySpec(SECRET.getBytes(), AES);
cipher = Cipher.getInstance(AES);
}
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
i am learning encryption in java and used these two tutorials yet This from Code2learn
and This from howtodoinjava.com
when i try to encrypt hello from these example code both gives different encrypted strings, i have tried a lot to find that what is the main difference between these examples that is causing different encrypted strings of same passwords as both are using AES ..
Code from code 2 learn
package nomad;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.*;
import sun.misc.*;
public class AESencrp {
private static final String ALGO = "AES";
private static final byte[] keyValue =
new byte[] { 'T', 'h', 'e', 'B', 'e', 's', 't',
'S', 'e', 'c', 'r','e', 't', 'K', 'e', 'y' };
public static String encrypt(String Data) throws Exception {
Key key = generateKey();
Cipher c = Cipher.getInstance(ALGO);
c.init(Cipher.ENCRYPT_MODE, key);
byte[] encVal = c.doFinal(Data.getBytes());
String encryptedValue = new BASE64Encoder().encode(encVal);
return encryptedValue;
}
public static String decrypt(String encryptedData) throws Exception {
Key key = generateKey();
Cipher c = Cipher.getInstance(ALGO);
c.init(Cipher.DECRYPT_MODE, key);
byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData);
byte[] decValue = c.doFinal(decordedValue);
String decryptedValue = new String(decValue);
return decryptedValue;
}
private static Key generateKey() throws Exception {
Key key = new SecretKeySpec(keyValue, ALGO);
return key;
}
}
package nomad;
public class Checker {
public static void main(String[] args) throws Exception {
String password = "mypassword";
String passwordEnc = AESencrp.encrypt(password);
String passwordDec = AESencrp.decrypt(passwordEnc);
System.out.println("Plain Text : " + password);
System.out.println("Encrypted Text : " + passwordEnc);
System.out.println("Decrypted Text : " + passwordDec);
}
}
Code for how to do in java
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class AES {
private static SecretKeySpec secretKey;
private static byte[] key;
public static void setKey(String myKey)
{
MessageDigest sha = null;
try {
key = myKey.getBytes("UTF-8");
sha = MessageDigest.getInstance("SHA-1");
key = sha.digest(key);
key = Arrays.copyOf(key, 16);
secretKey = new SecretKeySpec(key, "AES");
}
catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
public static String encrypt(String strToEncrypt, String secret)
{
try
{
setKey(secret);
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
return Base64.getEncoder().encodeToString(cipher.doFinal(strToEncrypt.getBytes("UTF-8")));
}
catch (Exception e)
{
System.out.println("Error while encrypting: " + e.toString());
}
return null;
}
public static String decrypt(String strToDecrypt, String secret)
{
try
{
setKey(secret);
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
return new String(cipher.doFinal(Base64.getDecoder().decode(strToDecrypt)));
}
catch (Exception e)
{
System.out.println("Error while decrypting: " + e.toString());
}
return null;
}
}
public static void main(String[] args)
{
final String secretKey = "ssshhhhhhhhhhh!!!!";
String originalString = "howtodoinjava.com";
String encryptedString = AES.encrypt(originalString, secretKey) ;
String decryptedString = AES.decrypt(encryptedString, secretKey) ;
System.out.println(originalString);
System.out.println(encryptedString);
System.out.println(decryptedString);
}
I have added the codes as one of the comments says that external links are not accessible by everyone .
Keep in mind that secretkeys and passowrd are the same in my code.
Adding my own code..
name it as code 1
AES Class
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.Base64;
public class AES {
public static SecretKeySpec secretKeySpec;
private static byte[] key;
public static String setKey(String myKey) throws Exception {
MessageDigest sha=null;
key =myKey.getBytes("UTF-8");
sha=MessageDigest.getInstance("SHA-1");
key=sha.digest(key);
key= Arrays.copyOf(key,16);
secretKeySpec=new SecretKeySpec(key,"AES");
return myKey;
}
public static String encrypt(String strToencrypt, String secret) throws Exception {
String s= setKey(secret);
System.out.println(s);
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE,secretKeySpec);
return Base64.getEncoder().encodeToString(cipher.doFinal(strToencrypt.getBytes("UTF-8")));
}
public static String decryt(String strToDec , String secret) throws Exception {
setKey(secret);
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE,secretKeySpec);
return new String(cipher.doFinal(Base64.getDecoder().decode(strToDec)));
}
}
Main Class of above AES Class
public class Main {
public static void main(String[] args) throws Exception {
AES aes = new AES();
String ss=null;
String sd=null;
ss=aes.encrypt("hello","TheBestSecretKey");
sd=aes.decryt(ss,"TheBestSecretKey");
System.out.println("The Encrypted == " + ss);
System.out.println("The Decrypted == " + sd);
}
}
Another Code
Name It as Code 2
package sample;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Base64;
public class Main {
private static final String ALGO ="AES";
private static String string = "TheBestSecretKey";
private static byte[] key ;
private static SecretKeySpec secretKeySpec;
public static String aesEncrypt(String en) throws Exception {
Key key = new SecretKeySpec(string.getBytes(),ALGO);
Cipher c = Cipher.getInstance("AES/ECB/PKCS5Padding");
c.init(Cipher.ENCRYPT_MODE,key);
byte[] encValue =c.doFinal(en.getBytes("UTF-8"));
String encryptedValue= new BASE64Encoder().encode(encValue);
return encryptedValue;
}
public static String aesDecrypt(String De) throws Exception{
Key key = new SecretKeySpec(string.getBytes(),"AES");
Cipher c = Cipher.getInstance("AES/ECB/PKCS5Padding");
c.init(Cipher.DECRYPT_MODE,key);
// return new String(c.doFinal(Base64.getDecoder().decode(De)));
byte[]decodedVlue=new BASE64Decoder().decodeBuffer(De);
byte[] decValue = c.doFinal(decodedVlue);
String deccryptedValue = new String(decValue);
return deccryptedValue;
}
public static void main(String[] args) throws Exception {
String password = "hello";
String passEnc= Main.aesEncrypt(password);
System.out.println(passEnc);
String passDec = Main.aesDecrypt(passEnc);
System.out.println(passDec);
}
}
here are the codes
now i am also posting encrypted strings
using SecretSpecKey TheBestSecretKey and hello as the string to be encrypted
CODE 1 UlQiIs/K0EwcSKbWMjcT1g==
CODE 2 hHDBo1dJYj5RcjdFA6BBfw==
I created ciphertext with javax.crypto.Cipher org.apache.commons.codec.binary.Base64 and using Java like following:
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final class PwdCipher {
private static final Logger LOG = LoggerFactory.getLogger(PwdCipher.class);
private static final int BASE64_ARG0 = 32;
private static final String SECRET = "tvnw63ufg9gh5392";
private static byte[] linebreak = {};
private static SecretKey key;
private static Cipher cipher;
private static Base64 coder;
static {
key = new SecretKeySpec(SECRET.getBytes(), "AES");
try {
cipher = Cipher.getInstance("AES/ECB/PKCS5Padding", "SunJCE");
} catch (NoSuchAlgorithmException | NoSuchProviderException | NoSuchPaddingException e) {
LOG.debug("Erro ao criar encriptador.", e);
}
coder = new Base64(BASE64_ARG0, linebreak, true);
}
private PwdCipher(){
}
public static synchronized String encrypt(String plainText) {
try {
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] cipherText = cipher.doFinal(plainText.getBytes());
return new String(coder.encode(cipherText));
} catch (Exception e) {
throw new GdocException("Erro ao encriptar senha.", e);
}
}
public static synchronized String decrypt(String codedText) {
try {
byte[] encypted = coder.decode(codedText.getBytes());
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] decrypted = cipher.doFinal(encypted);
return new String(decrypted);
} catch (Exception e) {
throw new GdocException("Erro ao decriptar senha.", e);
}
}
}
I need to decrypt the text (encrypted with class PwdCipher) using Node.js, but when I use the following code:
exports.decryptLdapPassword = function(password){
var key = 'tvnw63ufg9gh5392';
var ciphertext = password;
var crypto = require('crypto');
var decipher = crypto.createDecipher('aes-128-ecb', key);
var decrypted = decipher.update(ciphertext, 'base64', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
};
It turns out the following exception:
> crypto.js:323 var ret = this._binding.final();
> ^ TypeError: error:00000000:lib(0):func(0):reason(0)
> at Decipher.Cipher.final (crypto.js:323:27)
> at Object.exports.decryptLdapPassword (C:\ProjetosTFS\GDOC\fSuporte\GDoc\Versionado\Fontes\woodstock\server\api\service\service.util.js:14:25)
> at Promise.<anonymous> (C:\ProjetosTFS\GDOC\fSuporte\GDoc\Versionado\Fontes\woodstock\server\api\service\service.controller.js:111:34)
> at Promise.<anonymous> (C:\ProjetosTFS\GDOC\fSuporte\GDoc\Versionado\Fontes\woodstock\node_modules\mongoose\node_modules\mpromise\lib\promise.js:177:8)
> at Promise.emit (events.js:95:17)
> at Promise.emit (C:\ProjetosTFS\GDOC\fSuporte\GDoc\Versionado\Fontes\woodstock\node_modules\mongoose\node_modules\mpromise\lib\promise.js:84:38)
> at Promise.fulfill (C:\ProjetosTFS\GDOC\fSuporte\GDoc\Versionado\Fontes\woodstock\node_modules\mongoose\node_modules\mpromise\lib\promise.js:97:20)
> at Promise.resolve (C:\ProjetosTFS\GDOC\fSuporte\GDoc\Versionado\Fontes\woodstock\node_modules\mongoose\lib\promise.js:114:23)
> at Promise.<anonymous> (C:\ProjetosTFS\GDOC\fSuporte\GDoc\Versionado\Fontes\woodstock\node_modules\mongoose\node_modules\mpromise\lib\promise.js:177:8)
> at Promise.emit (events.js:95:17)
Any idea?
Worked! Solution published in https://github.com/joyent/node/issues/20983#issuecomment-100885608
I wrote a utility program to do encryption and decryption using AES algorithm. Regular program works fine but when I run test with same method I am getting Cipher initialization error on doFinal method.
I did some research and some suggest to put init and doFinal in a synchronized block. I did that and still getting same exception.
I also updated US_export_policy.jar and local_policy.jar in jre7/lib/security folder as suggested by some forum. Still getting same issue.
What could be wrong in the code?
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.apache.log4j.Logger;
public class CipherUtil {
private static Logger log = Logger.getLogger(CipherUtil.class);
private static final String SECRET_KEY = "000102030405060708090A0B0C0D0E0F";
private Cipher cipher;
private SecretKeySpec secretKeySpec;
private static CipherUtil cipherUtil;
private CipherUtil() {
try {
cipher = Cipher.getInstance("AES");
} catch (NoSuchAlgorithmException | NoSuchPaddingException ex) {
log.error(ex);
}
byte[] key = null;
try {
key = Hex.decodeHex(SECRET_KEY.toCharArray());
} catch (DecoderException ex) {
log.error(ex);
}
secretKeySpec = new SecretKeySpec(key, "AES");
}
public static synchronized CipherUtil getCipherUtilObject() {
if (cipherUtil == null) {
cipherUtil = new CipherUtil();
}
return cipherUtil;
}
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
public String encrypt(String plainText) {
if (plainText == null)
return null;
String encryptedText = null;
byte[] encrypted = null;
synchronized (cipher) {
try {
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
} catch (InvalidKeyException e) {
log.error(e.getMessage());
}
}
synchronized (cipher) {
try {
encrypted = cipher.doFinal(plainText.getBytes("UTF-8"));
encryptedText = new String(Base64.encodeBase64(encrypted));
} catch (IllegalBlockSizeException | BadPaddingException
| UnsupportedEncodingException e) {
log.error(e.getMessage());
}
}
return encryptedText;
}
public synchronized String decrypt(String encryptedText) {
if (encryptedText == null)
return null;
byte[] toDecrypt = null;
byte[] original = null;
String decryptedText = null;
synchronized (cipher) {
try {
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
} catch (InvalidKeyException e) {
log.error(e.getMessage());
}
}
toDecrypt = Base64.decodeBase64(encryptedText);
synchronized (cipher) {
try {
original = cipher.doFinal(toDecrypt);
} catch (IllegalBlockSizeException | BadPaddingException e) {
log.error(e.getMessage());
}
}
try {
decryptedText = new String(original, "UTF-8");
} catch (UnsupportedEncodingException e) {
log.error(e.getMessage());
}
return decryptedText;
}
}
and the test class:
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.hamcrest.core.IsNot.not;
import static org.junit.Assert.assertThat;
import org.junit.Before;
import org.junit.Test;
public class CipherTest {
CipherUtil cipherUtil;
#Before
public void setUp() {
cipherUtil = CipherUtil.getCipherUtilObject();
}
#Test
public void testEncryptDecrypt() {
String plainText = "Secret Message";
String encryptedText = cipherUtil.encrypt(plainText);
assertThat(encryptedText, not(equalTo(plainText)));
String decryptedText = cipherUtil.decrypt(encryptedText);
assertThat(decryptedText, is(equalTo(plainText)));
assertThat(encryptedText, not(equalTo(decryptedText)));
}
}
and finally this is the exception:
java.lang.IllegalStateException: Cipher not initialized
at javax.crypto.Cipher.checkCipherState(Cipher.java:1672)
at javax.crypto.Cipher.doFinal(Cipher.java:2079)
at com.testapp.util.CipherUtil.encrypt(CipherUtil.java:67)
at com.testapp.util.CipherTest.testEncryptDecrypt(CipherTest.java:23)
The code ran fine on my machine. Note that your encrypt method is not synchronized, so running this in a threaded environment will make it fail. In general you should have one Cipher instance per thread. Cipher contains state between method calls, so just synchronizing access to the method calls themselves will fail from time to time.
I'm trying to create a class that will allow me to encrypt and decrypt strings using the AES algorithm. I'm using the exception from http://aesencryption.net/#Java-aes-encryption-example but have modified the code to suit my needs.
This is my Main.java:
public class Main {
public static void main(String[] args) {
AES256 aes = new AES256();
aes.setKey("Secret Key");
String enc = "";
enc = aes.encrypt("qwertyuiopasdfgh");
System.out.println(enc);
System.out.println(aes.decrypt(enc));
}
}
And this is my AES256.java:
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Base64;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
public class AES256 {
private SecretKeySpec secretKey;
private byte[] key;
public void setKey(String key) {
MessageDigest sha = null;
try {
this.key = key.getBytes("UTF-8");
sha = MessageDigest.getInstance("SHA-1");
this.key = sha.digest(this.key);
this.key = Arrays.copyOf(this.key, 16);
secretKey = new SecretKeySpec(this.key, "AES");
} catch (UnsupportedEncodingException | NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
public String getSecretKey() {
return secretKey.toString();
}
public String getKey() {
return new String(key);
}
public String encrypt(String string) {
try {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
return Base64.getMimeEncoder().encodeToString(string.getBytes());
} catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException e) {
e.printStackTrace();
}
return null;
}
public String decrypt(String string) {
try {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
return new String(cipher.doFinal(Base64.getMimeDecoder().decode(string.getBytes())));
} catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException e) {
e.printStackTrace();
}
return null;
}
}
This is the error that is being thrown:
javax.crypto.BadPaddingException: Given final block not properly padded
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:966)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:824)
at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:436)
at javax.crypto.Cipher.doFinal(Cipher.java:2121)
at AES256.decrypt(AES256.java:55)
at Main.main(Main.java:13)
Does anybody know what is causing this error?
You return the original string in its base64-encoded form:
return Base64.getMimeEncoder().encodeToString(string.getBytes());
You'd want to use the cipher in there as well:
return Base64.getMimeEncoder().encodeToString(cipher.doFinal(string.getBytes()));
Independent of that, when depolying own crypto please be aware of the impacts of cipher modes, padding, etc. For example the ECB mode you're using will produce the same ciphertext from the same plaintext, e.g. the ciphertext might lead hints about the original text, as in the famous encrypted tux image:
Image Copyright: All uses are permitted provided that Larry Ewing, the owner of the original image, who requires that you mention him, his email address, lewing#isc.tamu.edu, and The GIMP, according to http://www.isc.tamu.edu/~lewing/linux/.
For more details on that, see Wikipedia's article about block cipher modes.
I'm implementing OpenID Connect code flow, and I'm a bit confused on how to use the client secret as a key when using javax.crypto.Mac for generating the HMACSHA-256 signature. I can't figure out how to convert the client ID to key bytes.
import org.apache.commons.codec.Charsets;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
public class HMACSigner {
public static final String HMACSHA256 = "HmacSHA256";
public String createSignature(final String messageToSign, final String clientSecret) {
// How do I convert the client secret to the key byte array?
SecretKeySpec secretKey = new SecretKeySpec(clientSecret.getBytes(Charsets.UTF_8), HMACSHA256);
try {
Mac mac = Mac.getInstance(HMACSHA256);
mac.init(secretKey);
byte[] bytesToSign = messageToSign.getBytes(Charsets.US_ASCII);
byte[] signature = mac.doFinal(bytesToSign);
return Base64.encodeBase64URLSafeString(signature);
}
catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
catch (InvalidKeyException e) {
throw new RuntimeException(e);
}
}
}
Following the example at https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-web-signature-17#appendix-A, I've created the following test case. My output is ZekyXWlxvuCN9H8cuDrZfaRa3pMJhHpv6QKFdUqXbLc.
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class HMACSignerTest {
private HMACSigner sut;
#Test
public void should_create_signature_according_to_spec() {
sut = new HMACSigner();
String signature = sut.createSignature("eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ",
"AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow");
assertEquals("dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk", signature);
}
}
The key seems to be Base64 encoded:
SecretKeySpec secretKey = new SecretKeySpec(Base64.decodeBase64(clientSecret), HMACSHA256);