updated encryption class to include AbstractJwtEncrypter
parent
caf2a7b494
commit
cee44de3d1
|
@ -0,0 +1,29 @@
|
||||||
|
package org.mitre.jwt.encryption;
|
||||||
|
|
||||||
|
import org.mitre.jwe.model.Jwe;
|
||||||
|
import org.mitre.jwt.encryption.impl.RsaDecrypter;
|
||||||
|
|
||||||
|
|
||||||
|
public abstract class AbstractJweDecrypter implements JwtDecrypter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Jwe decrypt(Jwe jwe) {
|
||||||
|
String alg = jwe.getHeader().getAlgorithm();
|
||||||
|
if(alg.equals("RS256") || alg.equals("RS384") || alg.equals("RS512")) {
|
||||||
|
|
||||||
|
RsaDecrypter decrypter = new RsaDecrypter(jwe);
|
||||||
|
jwe.setCiphertext(decrypter.decryptCipherText(jwe).getBytes()); //TODO: When decrypting, should it return a jwe or jwt?
|
||||||
|
jwe.setEncryptedKey(decrypter.decryptEncryptionKey(jwe));
|
||||||
|
|
||||||
|
} else if(alg.equals("HS256") || alg.equals("HS384") || alg.equals("HS512")){
|
||||||
|
|
||||||
|
throw new IllegalArgumentException("Cannot use Hmac for decryption");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Not a valid decrypting algorithm");
|
||||||
|
}
|
||||||
|
|
||||||
|
return jwe;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,41 +1,145 @@
|
||||||
package org.mitre.jwt.encryption;
|
package org.mitre.jwt.encryption;
|
||||||
|
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.interfaces.RSAPrivateKey;
|
||||||
|
import java.security.interfaces.RSAPublicKey;
|
||||||
|
|
||||||
|
import javax.crypto.BadPaddingException;
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import javax.crypto.IllegalBlockSizeException;
|
||||||
|
import javax.crypto.NoSuchPaddingException;
|
||||||
|
|
||||||
import org.mitre.jwe.model.Jwe;
|
import org.mitre.jwe.model.Jwe;
|
||||||
import org.mitre.jwt.signer.impl.HmacSigner;
|
import org.mitre.jwe.model.JweHeader;
|
||||||
import org.mitre.jwt.signer.impl.RsaSigner;
|
import org.mitre.jwt.model.JwtClaims;
|
||||||
|
|
||||||
|
|
||||||
public abstract class AbstractJweEncrypter implements JwtEncrypter {
|
public abstract class AbstractJweEncrypter implements JwtEncrypter {
|
||||||
|
|
||||||
@Override
|
private Jwe jwe;
|
||||||
public Jwe encrypt(Jwe jwe) {
|
|
||||||
|
private JweHeader header;
|
||||||
jwe.setCiphertext(encryptClaims(jwe));
|
|
||||||
jwe.setEncryptedKey(encryptKey(jwe));
|
private JwtClaims claims;
|
||||||
|
|
||||||
String alg = jwe.getHeader().getAlgorithm();
|
private String signature;
|
||||||
if(alg.equals("RS256") || alg.equals("RS384") || alg.equals("RS512")) {
|
|
||||||
RsaSigner rsaSigner = new RsaSigner();
|
private byte[] encryptedKey;
|
||||||
try {
|
|
||||||
jwe = (Jwe) rsaSigner.sign(jwe);
|
private byte[] cipherText;
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
// TODO Auto-generated catch block
|
public Jwe getJwe() {
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
} else if(alg.equals("HS256") || alg.equals("HS384") || alg.equals("HS512")){
|
|
||||||
HmacSigner hmacSigner = new HmacSigner();
|
|
||||||
try {
|
|
||||||
jwe = (Jwe) hmacSigner.sign(jwe);
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Not a valid signing algorithm");
|
|
||||||
}
|
|
||||||
|
|
||||||
return jwe;
|
return jwe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setJwe(Jwe jwe) {
|
||||||
|
this.jwe = jwe;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getEncryptecKey() {
|
||||||
|
return encryptedKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEncryptedKey(byte[] encryptedKey) {
|
||||||
|
this.encryptedKey = encryptedKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JweHeader getHeader() {
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeader(JweHeader header) {
|
||||||
|
this.header = header;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JwtClaims getClaims() {
|
||||||
|
return claims;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClaims(JwtClaims claims) {
|
||||||
|
this.claims = claims;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSignature() {
|
||||||
|
return signature;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSignature(String signature) {
|
||||||
|
this.signature = signature;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getCipherText() {
|
||||||
|
return cipherText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCipherText(byte[] cipherText) {
|
||||||
|
this.cipherText = cipherText;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public byte[] encryptKey(Jwe jwe){
|
||||||
|
|
||||||
|
RSAPublicKey publicKey = null; // TODO: placeholder
|
||||||
|
RSAPrivateKey privateKey = null;
|
||||||
|
|
||||||
|
Cipher cipher;
|
||||||
|
try {
|
||||||
|
cipher = Cipher.getInstance("RSA");
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
||||||
|
encryptedKey = cipher.doFinal(privateKey.getEncoded());
|
||||||
|
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (NoSuchPaddingException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InvalidKeyException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IllegalBlockSizeException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (BadPaddingException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return encryptedKey;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] encryptClaims(Jwe jwe) {
|
||||||
|
|
||||||
|
RSAPublicKey publicKey = null; // TODO: placeholder
|
||||||
|
|
||||||
|
Cipher cipher;
|
||||||
|
try {
|
||||||
|
cipher = Cipher.getInstance("RSA");
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
||||||
|
cipherText = cipher.doFinal(claims.toString().getBytes());
|
||||||
|
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (NoSuchPaddingException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InvalidKeyException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IllegalBlockSizeException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (BadPaddingException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return cipherText;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
package org.mitre.jwt.encryption;
|
|
||||||
|
|
||||||
public class IntegrityProtection {
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,11 +1,14 @@
|
||||||
package org.mitre.jwt.encryption;
|
package org.mitre.jwt.encryption;
|
||||||
|
|
||||||
import org.mitre.jwt.model.Jwt;
|
import org.mitre.jwe.model.Jwe;
|
||||||
|
|
||||||
public class JwtDecrypter {
|
public interface JwtDecrypter {
|
||||||
|
|
||||||
|
public Jwe decrypt(Jwe jwe);
|
||||||
|
|
||||||
|
public String decryptCipherText(Jwe jwe);
|
||||||
|
|
||||||
|
public byte[] decryptEncryptionKey(Jwe jwe);
|
||||||
|
|
||||||
public JwtDecrypter(Jwt jwt) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,6 @@ public interface JwtEncrypter {
|
||||||
|
|
||||||
public byte[] encryptClaims(Jwe jwe);
|
public byte[] encryptClaims(Jwe jwe);
|
||||||
|
|
||||||
public Jwe encrypt(Jwe jwe);
|
public Jwe encryptAndSign(Jwe jwe);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,9 +11,9 @@ import javax.crypto.IllegalBlockSizeException;
|
||||||
import javax.crypto.NoSuchPaddingException;
|
import javax.crypto.NoSuchPaddingException;
|
||||||
|
|
||||||
import org.mitre.jwe.model.Jwe;
|
import org.mitre.jwe.model.Jwe;
|
||||||
import org.mitre.jwt.model.JwtClaims;
|
import org.mitre.jwt.encryption.AbstractJweDecrypter;
|
||||||
|
|
||||||
public class RsaDecrypter {
|
public class RsaDecrypter extends AbstractJweDecrypter {
|
||||||
|
|
||||||
private Jwe jwe;
|
private Jwe jwe;
|
||||||
|
|
||||||
|
@ -48,8 +48,9 @@ public class RsaDecrypter {
|
||||||
public void setPublicKey(PublicKey publicKey) {
|
public void setPublicKey(PublicKey publicKey) {
|
||||||
this.publicKey = publicKey;
|
this.publicKey = publicKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String decryptCipherText() {
|
@Override
|
||||||
|
public String decryptCipherText(Jwe jwe) {
|
||||||
Cipher cipher;
|
Cipher cipher;
|
||||||
String clearTextString = null;
|
String clearTextString = null;
|
||||||
try {
|
try {
|
||||||
|
@ -80,7 +81,8 @@ public class RsaDecrypter {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] decryptEncryptionKey() {
|
@Override
|
||||||
|
public byte[] decryptEncryptionKey(Jwe jwe) {
|
||||||
Cipher cipher;
|
Cipher cipher;
|
||||||
byte[] unencryptedKey = null;
|
byte[] unencryptedKey = null;
|
||||||
|
|
||||||
|
@ -109,13 +111,5 @@ public class RsaDecrypter {
|
||||||
|
|
||||||
return unencryptedKey;
|
return unencryptedKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Jwe decrypt(Jwe jwe) {
|
|
||||||
|
|
||||||
jwe.setClaims(new JwtClaims(decryptCipherText()));
|
|
||||||
jwe.setEncryptedKey(decryptEncryptionKey());
|
|
||||||
|
|
||||||
return jwe;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,34 +1,13 @@
|
||||||
package org.mitre.jwt.encryption.impl;
|
package org.mitre.jwt.encryption.impl;
|
||||||
|
|
||||||
import java.security.InvalidKeyException;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.interfaces.RSAPrivateKey;
|
|
||||||
import java.security.interfaces.RSAPublicKey;
|
|
||||||
|
|
||||||
import javax.crypto.BadPaddingException;
|
|
||||||
import javax.crypto.Cipher;
|
|
||||||
import javax.crypto.IllegalBlockSizeException;
|
|
||||||
import javax.crypto.NoSuchPaddingException;
|
|
||||||
|
|
||||||
import org.mitre.jwe.model.Jwe;
|
import org.mitre.jwe.model.Jwe;
|
||||||
import org.mitre.jwe.model.JweHeader;
|
|
||||||
import org.mitre.jwt.encryption.AbstractJweEncrypter;
|
import org.mitre.jwt.encryption.AbstractJweEncrypter;
|
||||||
import org.mitre.jwt.model.JwtClaims;
|
import org.mitre.jwt.signer.impl.RsaSigner;
|
||||||
|
|
||||||
public class RsaEncrypter extends AbstractJweEncrypter {
|
public class RsaEncrypter extends AbstractJweEncrypter {
|
||||||
|
|
||||||
private Jwe jwe;
|
|
||||||
|
|
||||||
private JweHeader header;
|
|
||||||
|
|
||||||
private JwtClaims claims;
|
|
||||||
|
|
||||||
private String signature;
|
|
||||||
|
|
||||||
private byte[] encryptedKey;
|
|
||||||
|
|
||||||
private byte[] cipherText;
|
|
||||||
|
|
||||||
public RsaEncrypter(Jwe jwe) {
|
public RsaEncrypter(Jwe jwe) {
|
||||||
setJwe(jwe);
|
setJwe(jwe);
|
||||||
setHeader(jwe.getHeader());
|
setHeader(jwe.getHeader());
|
||||||
|
@ -36,126 +15,31 @@ public class RsaEncrypter extends AbstractJweEncrypter {
|
||||||
setSignature(jwe.getSignature());
|
setSignature(jwe.getSignature());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Jwe getJwe() {
|
@Override
|
||||||
|
public Jwe encryptAndSign(Jwe jwe) {
|
||||||
|
|
||||||
|
String alg = jwe.getHeader().getAlgorithm();
|
||||||
|
if(alg.equals("RS256") || alg.equals("RS384") || alg.equals("RS512")) {
|
||||||
|
|
||||||
|
jwe.setCiphertext(encryptClaims(jwe));
|
||||||
|
jwe.setEncryptedKey(encryptKey(jwe));
|
||||||
|
|
||||||
|
RsaSigner rsaSigner = new RsaSigner(); //TODO: Add parameters to RsaSigner. ie: keys from keystore (null at the moment)
|
||||||
|
try {
|
||||||
|
jwe = (Jwe) rsaSigner.sign(jwe);
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
} else if(alg.equals("HS256") || alg.equals("HS384") || alg.equals("HS512")){
|
||||||
|
|
||||||
|
throw new IllegalArgumentException("Cannot use Hmac for encryption");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Not a valid signing algorithm");
|
||||||
|
}
|
||||||
|
|
||||||
return jwe;
|
return jwe;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setJwe(Jwe jwe) {
|
|
||||||
this.jwe = jwe;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getEncryptecKey() {
|
|
||||||
return encryptedKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEncryptedKey(byte[] encryptedKey) {
|
|
||||||
this.encryptedKey = encryptedKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public JweHeader getHeader() {
|
|
||||||
return header;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHeader(JweHeader header) {
|
|
||||||
this.header = header;
|
|
||||||
}
|
|
||||||
|
|
||||||
public JwtClaims getClaims() {
|
|
||||||
return claims;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setClaims(JwtClaims claims) {
|
|
||||||
this.claims = claims;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSignature() {
|
|
||||||
return signature;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSignature(String signature) {
|
|
||||||
this.signature = signature;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getCipherText() {
|
|
||||||
return cipherText;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCipherText(byte[] cipherText) {
|
|
||||||
this.cipherText = cipherText;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] encryptKey(Jwe jwe){
|
|
||||||
String alg = jwe.getHeader().getAlgorithm();
|
|
||||||
RSAPublicKey publicKey = null; // TODO: placeholder
|
|
||||||
RSAPrivateKey privateKey = null;
|
|
||||||
|
|
||||||
if(alg.equals("RS256") || alg.equals("RS384") || alg.equals("RS512")) {
|
|
||||||
Cipher cipher;
|
|
||||||
try {
|
|
||||||
cipher = Cipher.getInstance("RSA");
|
|
||||||
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
|
||||||
encryptedKey = cipher.doFinal(privateKey.getEncoded());
|
|
||||||
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (NoSuchPaddingException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (InvalidKeyException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IllegalBlockSizeException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (BadPaddingException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Not a valid algorithm for encryption");
|
|
||||||
}
|
|
||||||
|
|
||||||
return encryptedKey;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] encryptClaims(Jwe jwe) {
|
|
||||||
String alg = jwe.getHeader().getAlgorithm();
|
|
||||||
RSAPublicKey publicKey = null; // TODO: placeholder
|
|
||||||
|
|
||||||
if(alg.equals("RS256") || alg.equals("RS384") || alg.equals("RS512")) {
|
|
||||||
Cipher cipher;
|
|
||||||
try {
|
|
||||||
cipher = Cipher.getInstance("RSA");
|
|
||||||
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
|
||||||
cipherText = cipher.doFinal(claims.toString().getBytes());
|
|
||||||
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (NoSuchPaddingException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (InvalidKeyException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IllegalBlockSizeException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (BadPaddingException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Not a valid algorithm for encryption");
|
|
||||||
}
|
|
||||||
|
|
||||||
return cipherText;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
package org.mitre.jwt.encryption.impl;
|
|
||||||
|
|
||||||
import java.security.InvalidKeyException;
|
|
||||||
import java.security.Key;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.PublicKey;
|
|
||||||
|
|
||||||
import javax.crypto.Cipher;
|
|
||||||
import javax.crypto.NoSuchPaddingException;
|
|
||||||
|
|
||||||
public class RsaJwtDecrypter {
|
|
||||||
|
|
||||||
PublicKey publicKey;
|
|
||||||
byte[] wrappedKey;
|
|
||||||
String algorithm;
|
|
||||||
|
|
||||||
public RsaJwtDecrypter(String algorithm, PublicKey publicKey, byte[] wrappedKey){
|
|
||||||
setPublicKey(publicKey);
|
|
||||||
setWrappedKey(wrappedKey);
|
|
||||||
setAlgorithm(algorithm);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PublicKey getPublicKey() {
|
|
||||||
return publicKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPublicKey(PublicKey publicKey) {
|
|
||||||
this.publicKey = publicKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getWrappedKey() {
|
|
||||||
return wrappedKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setWrappedKey(byte[] wrappedKey) {
|
|
||||||
this.wrappedKey = wrappedKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAlgorithm() {
|
|
||||||
return algorithm;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAlgorithm(String algorithm) {
|
|
||||||
this.algorithm = algorithm;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Key keyDecrypter() throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
|
|
||||||
|
|
||||||
Cipher cipher = Cipher.getInstance("RSA");
|
|
||||||
cipher.init(Cipher.UNWRAP_MODE, publicKey);
|
|
||||||
Key unwrappedKey = cipher.unwrap(wrappedKey, algorithm, Cipher.PRIVATE_KEY);
|
|
||||||
|
|
||||||
return unwrappedKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue