64 lines
1.9 KiB
Java
64 lines
1.9 KiB
Java
package tech.loedige;
|
|
|
|
import javax.crypto.*;
|
|
import javax.crypto.spec.SecretKeySpec;
|
|
import java.security.InvalidKeyException;
|
|
import java.security.NoSuchAlgorithmException;
|
|
|
|
public class KeyStreamGenerator_AES_CTR extends KeyStreamGenerator {
|
|
|
|
private Cipher cipher;
|
|
private final byte[] state = new byte[16];
|
|
private final byte[] ctr = new byte[16];
|
|
private int currentByte=0;
|
|
|
|
public void initState(byte[] key, byte[] iv)
|
|
throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException {
|
|
if((iv.length!=16)||(key.length!=16)){
|
|
throw new IllegalArgumentException("Invalid input length");
|
|
}
|
|
System.arraycopy(iv,0,ctr,0,16);
|
|
|
|
SecretKey secretKey = new SecretKeySpec(key,"AES");
|
|
cipher = Cipher.getInstance("AES/ECB/NOPADDING");
|
|
cipher.init(Cipher.ENCRYPT_MODE,secretKey);
|
|
}
|
|
|
|
@Override
|
|
byte getNextKeyStreamByte(byte mByte) {
|
|
currentByte++;
|
|
if(currentByte>=16){
|
|
try {
|
|
updateStateBlock();
|
|
} catch (BadPaddingException | IllegalBlockSizeException e) {
|
|
e.printStackTrace();
|
|
}
|
|
currentByte=0;
|
|
}
|
|
return state[currentByte];
|
|
}
|
|
|
|
private void updateStateBlock()
|
|
throws BadPaddingException, IllegalBlockSizeException {
|
|
incrementCtr();
|
|
System.arraycopy(cipher.doFinal(ctr),0,state,0,16);
|
|
}
|
|
|
|
/**
|
|
* inkrementiert den counter
|
|
*/
|
|
private void incrementCtr(){
|
|
for(int i = 0; i<16; i++){
|
|
//falls das Byte die volle Länge erreicht hat findet ein Übertrag statt
|
|
if(ctr[i]==0xff){
|
|
ctr[i]=0x00;
|
|
}
|
|
else{
|
|
//falls das Byte nicht die volle Länge hat endet die Inkrementierung
|
|
ctr[i]++;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|