ChaCha20/src/tech/loedige/KeyStreamGenerator_AES_CTR.java
2020-10-18 21:40:18 +02:00

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;
}
}
}
}