密码未初始化 [英] Cipher not initialized
问题描述
我决定通过遵循通用和并发,使用通用对象池来重用密码对象.对象池.区别在于该文章使用的是Connection
,但我使用的是Cipher
.
I decided to use generic object pooling to reuse cipher object by following A Generic and Concurrent Object Pool . The different is that the article using Connection
, but I'm using Cipher
.
Eracom
Pool<Cipher> pool = new BoundedBlockingPool<Cipher>(5, new CipherPickerValidator(), new CipherPicker("xxxx"));
public Key unwrapKey(byte[] tmkByte) throws Exception {
Cipher cipher = pool.get();
System.out.println("Cipher :" + cipher);
try{
cipher.init(Cipher.DEPT_MODE, mkkey, alSpec);
}catch(Exception e)
{
System.out.println(e);
}
byte[] de = cipher.doFinal(tmkByte);
SecretKey tmk = new SecretKeySpec(de, "De");
return tmk;
}
BoundedBlockingPool
public BoundedBlockingPool(
int size,
Validator<T> validator,
ObjectFactory<T> objectFactory) {
super();
this.objectFactory = objectFactory;
this.size = size;
this.validator = validator;
objects = new LinkedBlockingQueue<T>(size);
initializeObjects();
shutdownCalled = false;
}
@Override
public T get(long timeOut, TimeUnit unit) {
if (!shutdownCalled) {
T t = null;
try {
t = objects.poll(timeOut, unit);
return t;
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
}
return t;
}
throw new IllegalStateException(
"Object pool is already shutdown");
}
@Override
public T get() {
if (!shutdownCalled) {
T t = null;
try {
t = objects.take();
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
}
return t;
}
throw new IllegalStateException(
"Object pool is already shutdown");
}
@Override
public void shutdown() {
shutdownCalled = true;
executor.shutdownNow();
clearResources();
}
private void clearResources() {
objects.stream().forEach((t) -> {
validator.invalidate(t);
});
}
@Override
protected void returnToPool(T t) {
if (validator.isValid(t)) {
executor.submit(new ObjectReturner(objects, t));
}
}
@Override
protected void handleInvalidReturn(T t) {
}
@Override
protected boolean isValid(T t) {
return validator.isValid(t);
}
private void initializeObjects() {
for (int i = 0; i < size; i++) {
objects.add(objectFactory.createNew());
}
}
private class ObjectReturner<E>
implements Callable<Void> {
private final BlockingQueue<E> queue;
private E e;
public ObjectReturner(BlockingQueue<E> queue, E e) {
this.queue = queue;
this.e = e;
}
@Override
public Void call() {
while (true) {
try {
queue.put(e);
break;
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
}
}
return null;
}
}
CipherPicker
public CipherPicker(String instances) {
super();
this.instance = instances;
}
@Override
public Cipher createNew() {
try {
System.out.print("Instances : " + instance);
return Cipher.getInstance(this.instance);
} catch (NoSuchAlgorithmException | NoSuchPaddingException se) {
throw new IllegalArgumentException(
"Unable to create new cipher", se);
}
}
错误
Cipher :javax.crypto.Cipher@45c74f8
<log realm="GenerateIPEK" at="Thu Apr 20 18:20:27.737 MYT 2017">
<error>
<exception name="Cipher not initialized">
java.lang.IllegalStateException: Cipher not initialized
at javax.crypto.Cipher.checkCipherState(Cipher.java:1750)
at javax.crypto.Cipher.doFinal(Cipher.java:2157)
at com.rh.host.EracomJCE.unwrapKey(EracomJCE.java:65)
at com.rh.host.tm.GenerateIPEK.doPrepare(GenerateIPEK.java:70)
at com.rh.host.tm.TxnSupport.prepare(TxnSupport.java:36)
at org.jpos.transaction.TransactionManager.prepare(TransactionManager.java:473)
at org.jpos.transaction.TransactionManager.prepare(TransactionManager.java:526)
at org.jpos.transaction.TransactionManager.run(TransactionManager.java:257)
at java.lang.Thread.run(Thread.java:745)
</exception>
</error>
有人可以告诉我这样做的正确方法是什么?被困了几天.我在正确的道路上吗?非常感谢!
Can someone tell me what are the correct way to do this ? Been stucked for several days. Am I on the correct path ??? Big thanks !
修改
假设我有两种方法,之后将被调用.所以我应该这样写吗?
Assuming I have two methods and will be called after this. So I should write like this ?
public Key unwrapKey(byte[] tmkByte) throws Exception {
Cipher cipher = pool.get();
byte[] de = cipher.doFinal(tmkByte);
SecretKey tmk = new SecretKeySpec(de, "De");
return tmk;
}
public Key wrapKey(byte[] tByte) throws Exception {
Cipher cipher = pool.get();
// byte,SecretKey...
}
推荐答案
我认为您的路径正确.我认为您需要在createNew()
方法中初始化Cipher
:
I think you're on the correct path. I think you need to initialize the Cipher
in the createNew()
method:
@Override
public Cipher createNew() {
try {
System.out.print("Instances : " + instance);
Cipther result = Cipher.getInstance(this.instance);
result.init(...); // use the right init params, e.g. opmode, crypto key
return result;
} catch (NoSuchAlgorithmException | NoSuchPaddingException se) {
throw new IllegalArgumentException(
"Unable to create new cipher", se);
}
}
这篇关于密码未初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!