使用BouncyCastle的ChaCha进行文件加密 [英] Using BouncyCastle's ChaCha for file encryption

查看:280
本文介绍了使用BouncyCastle的ChaCha进行文件加密的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望使用ChaCha加密几个文件,所以我想知道使用 Chacha20Poly1305 。看来这个类是为TLS设计的,那意味着它不是为文件加密而设计的?里面的方法,例如 encodePlaintext() decodeCiphertext()似乎与文本而不是二进制文件一起工作。 / p>

如果是这样,有没有人知道如何使用BC的ChaCha实现文件加密?

解决方案

您可以尝试这样的一行:

  public void doChaCha(boolean encrypt,InputStream is,OutputStream os,
byte [] key,byte [] iv)throws IOException {
CipherParameters cp = new KeyParameter(key);
ParametersWithIV params = new ParametersWithIV(cp,iv);
StreamCipher引擎=新的ChaChaEngine();
engine.init(encrypt,params);

byte in [] = new byte [8192];
byte out [] = new byte [8192];
int len = 0;
while(-1!=(len = is.read(in))){
len = engine.processBytes(in,0,len,out,0);
os.write(out,0,len);
}
}

public void encChaCha(InputStream is,OutputStream os,byte [] key,
byte [] iv)throws IOException {
doChaCha (true,is,os,key,iv);
}

public void decChaCha(InputStream is,OutputStream os,byte [] key,
byte [] iv)throws IOException {
doChaCha(false,is, os,key,iv);
}

请注意, ChaChaEngine 仅支持长度为128或256位的密钥,IV为64位。



这里是一些测试:

  @Test 
public void chachaText()throws IOException,NoSuchAlgorithmException {
String text =chacha.txt;
Files.write(Paths.get(text),Hello,World!。getBytes(StandardCharsets.UTF_8),
StandardOpenOption.CREATE);
chacha(text);
}

@Test
public void chachaBin()throws IOException,NoSuchAlgorithmException {
SecureRandom sr = SecureRandom.getInstanceStrong();
byte [] data = new byte [1024 * 1024 * 4];
sr.nextBytes(data);
String bin =chacha.bin;
Files.write(Paths.get(bin),data,StandardOpenOption.CREATE);
chacha(bin);
}

private void chacha(String file)throws NoSuchAlgorithmException,IOException {
SecureRandom sr = SecureRandom.getInstanceStrong();
byte [] key = new byte [32]; // 32为256位密钥或16为128位
字节[] iv =新字节[8]; // ChaCha20需要64位IV
sr.nextBytes(key);
sr.nextBytes(iv);
String dat = String.format(%s.dat,file);

try(InputStream is = new FileInputStream(file);
OutputStream os = new FileOutputStream(dat)){
encChaCha(is,os,key,iv);
}

try(InputStream is = new FileInputStream(dat);
ByteArrayOutputStream os = new ByteArrayOutputStream()){
decChaCha(is,os,key,iv );
byte [] actual = os.toByteArray();
byte [] expected = Files.readAllBytes(Paths.get(file));
Assert.assertArrayEquals(expected,actual);
}
}

编辑:解码字符串

  @Test 
public void chachaString()throws IOException,NoSuchAlgorithmException
{
String test =Hello,World!;

try(InputStream isEnc = new ByteArrayInputStream(test.getBytes(StandardCharsets.UTF_8));
ByteArrayOutputStream osEnc = new ByteArrayOutputStream())
{
SecureRandom sr = SecureRandom.getInstanceStrong();
byte [] key = new byte [32]; // 32为256位密钥或16为128位
字节[] iv =新字节[8]; // ChaCha20需要64位IV
sr.nextBytes(key);
sr.nextBytes(iv);

encChaCha(isEnc,osEnc,key,iv);

byte [] encoded = osEnc.toByteArray();

try(InputStream isDec = new ByteArrayInputStream(encoded);
ByteArrayOutputStream osDec = new ByteArrayOutputStream())
{
decChaCha(isDec,osDec,key,iv) ;

byte [] decoded = osDec.toByteArray();

String actual = new String(decode,StandardCharsets.UTF_8);

Assert.assertEquals(test,actual);
}
}
}


I'm hoping to encrypt a few files using ChaCha, so I wonder if it's appropriate to use Chacha20Poly1305. It seems that this class is designed for TLS, so does that mean it's not designed for file encryption? The methods inside, e.g., encodePlaintext() and decodeCiphertext() appear to work with text rather than binary files.

If that's the case, does anyone know how to work with BC's ChaCha implementation for file encryption?

解决方案

You could try something line this:

public void doChaCha(boolean encrypt, InputStream is, OutputStream os,
        byte[] key, byte[] iv) throws IOException {
    CipherParameters cp = new KeyParameter(key);
    ParametersWithIV params = new ParametersWithIV(cp, iv);
    StreamCipher engine = new ChaChaEngine();
    engine.init(encrypt, params);

    byte in[] = new byte[8192];
    byte out[] = new byte[8192];
    int len = 0;
    while(-1 != (len = is.read(in))) {
        len = engine.processBytes(in, 0 , len, out, 0);
        os.write(out, 0, len);
    }
}

public void encChaCha(InputStream is, OutputStream os, byte[] key,
        byte[] iv) throws IOException {
    doChaCha(true, is, os, key, iv);
}

public void decChaCha(InputStream is, OutputStream os, byte[] key,
        byte[] iv) throws IOException {
    doChaCha(false, is, os, key, iv);
}

Note that the ChaChaEngine supports only keys of the length 128 or 256 bits with an IV of 64 bits.

Here is some tests:

@Test
public void chachaText() throws IOException, NoSuchAlgorithmException {
    String text = "chacha.txt";
    Files.write(Paths.get(text), "Hello, World!".getBytes(StandardCharsets.UTF_8), 
        StandardOpenOption.CREATE);
    chacha(text);
}

@Test
public void chachaBin() throws IOException, NoSuchAlgorithmException {
    SecureRandom sr = SecureRandom.getInstanceStrong();
    byte[] data = new byte[1024*1024*4];
    sr.nextBytes(data);
    String bin = "chacha.bin";
    Files.write(Paths.get(bin), data, StandardOpenOption.CREATE);
    chacha(bin);
}

private void chacha(String file) throws NoSuchAlgorithmException, IOException {
    SecureRandom sr = SecureRandom.getInstanceStrong();
    byte[] key = new byte[32]; // 32 for 256 bit key or 16 for 128 bit
    byte[] iv = new byte[8]; // 64 bit IV required by ChaCha20
    sr.nextBytes(key);
    sr.nextBytes(iv);
    String dat = String.format("%s.dat", file);

    try(InputStream is = new FileInputStream(file); 
        OutputStream os = new FileOutputStream(dat)) {
        encChaCha(is, os, key, iv);
    }

    try(InputStream is = new FileInputStream(dat); 
        ByteArrayOutputStream os = new ByteArrayOutputStream()) {
        decChaCha(is, os, key, iv);
        byte[] actual = os.toByteArray();
        byte[] expected = Files.readAllBytes(Paths.get(file));
        Assert.assertArrayEquals(expected, actual);
    }
}

EDIT: encode / decode Strings

@Test
public void chachaString() throws IOException, NoSuchAlgorithmException
{
    String test = "Hello, World!";

    try (InputStream isEnc = new ByteArrayInputStream(test.getBytes(StandardCharsets.UTF_8));
            ByteArrayOutputStream osEnc = new ByteArrayOutputStream())
    {
        SecureRandom sr = SecureRandom.getInstanceStrong();
        byte[] key = new byte[32]; // 32 for 256 bit key or 16 for 128 bit
        byte[] iv = new byte[8]; // 64 bit IV required by ChaCha20
        sr.nextBytes(key);
        sr.nextBytes(iv);

        encChaCha(isEnc, osEnc, key, iv);

        byte[] encoded = osEnc.toByteArray();

        try (InputStream isDec = new ByteArrayInputStream(encoded);
                ByteArrayOutputStream osDec = new ByteArrayOutputStream())
        {
            decChaCha(isDec, osDec, key, iv);

            byte[] decoded = osDec.toByteArray();

            String actual = new String(decoded, StandardCharsets.UTF_8);

            Assert.assertEquals(test, actual);
        }
    }
}

这篇关于使用BouncyCastle的ChaCha进行文件加密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆