使用java中的vigenere加密加密字节数组 [英] Encrypt byte array using vigenere cipher in java

查看:186
本文介绍了使用java中的vigenere加密加密字节数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须使用vigenere加密来加密一些文件(jpg)。我写了一些代码,但加密和解密之后,我的文件被破坏了。第一个1/4的图像显示好,但其余部分已损坏。这是我的代码:

  @Override 
public byte [] encryptFile(byte [] file,String key){
char [] keyChars = key.toCharArray();
byte [] bytes = file; (int i = 0; i< file.length; i ++){
int keyNR = keyChars [i%keyChars.length] - 32;
int c = bytes [i]& 255;
if((c> = 32)&&(c <= 127)){
int x = c - 32;
x =(x + keyNR)%96;
bytes [i] =(byte)(x + 32);
}
}
返回字节;
}


@Override
public byte [] decryptFile(byte [] file,String key){
char [] keyChars = key.toCharArray ();
byte [] bytes = file; (int i = 0; i< file.length; i ++){
int keyNR = keyChars [i%keyChars.length] - 32;
int c = bytes [i]& 255;
if((c> = 32)&&(c <= 127)){
int x = c - 32;
x =(x - keyNR + 96)%96;
bytes [i] =(byte)(x + 32);
}
}
返回字节;
}

我做错了什么?



编辑:



阅读和写入文件:

  public void sendFile(String selectedFile,ICipher cipher,String key){
try {
DataOutputStream outStream = new DataOutputStream(client
.getOutputStream());
outStream.flush();
文件文件= new File(selectedFile);
FileInputStream fileStream = new FileInputStream(file);
long fileSize = file.length();
long completed = 0;
long bytesLeft = fileSize - completed;
String msg =SENDING_FILE:+ file.getName()+:+ fileSize;
outStream.writeUTF(cipher.encryptMsg(msg,key));
while(completed< fileSize){
int step =(int)(bytesLeft> 150000?150000:bytesLeft);
byte [] buffer = new byte [step];
fileStream.read(buffer);
buffer = cipher.encryptFile(buffer,key);
outStream.write(buffer);
完成+ =步;
bytesLeft = fileSize - completed;
}
outStream.writeUTF(cipher.encryptMsg(SEND_COMPLETE,key));
fileStream.close();
} catch(IOException e){
e.printStackTrace();
}

}

private void downloadFile(String fileName,int fileSize,DataInputStream input,ICipher cipher,String key){
try {
FileOutputStream outStream = new FileOutputStream(C:\\+ fileName);
int bytesRead = 0,counter = 0;

while(counter< fileSize){
int step =(int)(fileSize> 150000?150000:fileSize);
byte [] buffer = new byte [step];
bytesRead = input.read(buffer);
if(bytesRead> = 0){
buffer = cipher.decryptFile(buffer,key);
outStream.write(buffer,0,bytesRead);
counter + = bytesRead;
}
if(bytesRead< 1024){
outStream.flush();
break;
}
}

Display.getDefault()。syncExec(new Runnable(){
@Override
public void run(){
window.handleMessage(成功下载);
}
});
outStream.close();

} catch(Exception e){
Display.getDefault()。syncExec(new Runnable(){
@Override
public void run(){
window.handleMessage(下载文件时出错!);
}
});
}
}


解决方案

你以任何来自磁盘I / O的块编码文件:

  int step =(int)(bytesLeft> 150000? 150000:bytesLeft); 
byte [] buffer = new byte [step];
fileStream.read(buffer);
buffer = cipher.encryptFile(buffer,key);

但是您可以以任何来自网络I / O的块解码文件:

  bytesRead = input.read(buffer); 
if(bytesRead> = 0){
buffer = cipher.decryptFile(buffer,key);
outStream.write(buffer,0,bytesRead);
counter + = bytesRead;
}

这些块很可能不同意。磁盘I / O可能总是给你完整的块(对你来说很幸运),但网络I / O可能会给你分组大小的块(1500字节减去标题)。



密码应该获得已经编码/解码的数据的偏移量(或一次编码/解码所有内容),并使用它来适当地移动密钥,或者这可能发生:

 原始:... LOREM IPSUM ... 
键:... abCde abCde ...
编码:... MQUIR JRVYR ...
键:... abCde Cdeab ...<<<<注意键被移动
解码:... LOREM GNQXP .. 。<<在第一个块之后输出错误。

由于分组数据大小(以太网大小的TCP / IP数据包)以四个字节对齐,长度为4的键可能总是对齐。






另一个问题是您忽略读取的字节数从磁盘上传文件时。虽然磁盘I / O可能总是给您全尺寸的块(该文件可能是内存映射或底层本机API提供此保证),但没有任何理由认为是理所当然的。始终使用实际读取的字节数: bytesRead = fileStream.read(buffer);


I have to encrypt some file (jpg) using vigenere cipher. I wrote some code, but after encryption and decryption my file is corrupted. The first 1/4 of image displays okay, but the rest of it is corrupted. Here is my code:

@Override
public byte[] encryptFile(byte[] file, String key) {
    char[] keyChars = key.toCharArray();
    byte[] bytes = file;
    for (int i = 0; i < file.length; i++) {
        int keyNR = keyChars[i % keyChars.length] - 32;
        int c = bytes[i] & 255;
        if ((c >= 32) && (c <= 127)) {
            int x = c - 32;
            x = (x + keyNR) % 96;
            bytes[i] = (byte) (x + 32);
        }
    }
    return bytes;
}


@Override
public byte[] decryptFile(byte[] file, String key) {
    char[] keyChars = key.toCharArray();
    byte[] bytes = file;
    for (int i = 0; i < file.length; i++) {
        int keyNR = keyChars[i % keyChars.length] - 32;
        int c = bytes[i] & 255;
        if ((c >= 32) && (c <= 127)) {
            int x = c - 32;
            x = (x - keyNR + 96) % 96;
            bytes[i] = (byte) (x + 32);
        }
    }
    return bytes;
}

What did I do wrong?

EDIT:

reading and writing to file:

public void sendFile(String selectedFile, ICipher cipher, String key) {
    try {
        DataOutputStream outStream = new DataOutputStream(client
                .getOutputStream());
        outStream.flush();
        File file = new File(selectedFile);
        FileInputStream fileStream = new FileInputStream(file);
        long fileSize = file.length();
        long completed = 0;
        long bytesLeft = fileSize - completed;
        String msg = "SENDING_FILE:" + file.getName() + ":" + fileSize;
        outStream.writeUTF(cipher.encryptMsg(msg, key));
        while (completed < fileSize) {
            int step = (int) (bytesLeft > 150000 ? 150000 : bytesLeft);
            byte[] buffer = new byte[step];
            fileStream.read(buffer);
            buffer = cipher.encryptFile(buffer, key);
            outStream.write(buffer);
            completed += step;
            bytesLeft = fileSize - completed;
        }
        outStream.writeUTF(cipher.encryptMsg("SEND_COMPLETE", key));
        fileStream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }

}

    private void downloadFile(String fileName, int fileSize,DataInputStream input,ICipher cipher, String key) {
    try {
        FileOutputStream outStream = new FileOutputStream("C:\\" + fileName);
        int bytesRead = 0, counter = 0;

        while (counter < fileSize) {
            int step = (int) (fileSize > 150000 ? 150000 : fileSize);
            byte[] buffer = new byte[step];
            bytesRead = input.read(buffer);
            if (bytesRead >= 0) {
                buffer = cipher.decryptFile(buffer, key);
                outStream.write(buffer, 0, bytesRead);
                counter += bytesRead;
            }
            if (bytesRead < 1024) {
                outStream.flush();
                break;
            }
        }

        Display.getDefault().syncExec(new Runnable() {
            @Override
            public void run() {
                window.handleMessage("Download sucessfully");
            }
        });
        outStream.close();

    } catch (Exception e) {
        Display.getDefault().syncExec(new Runnable() {
            @Override
            public void run() {
                window.handleMessage("Error on downloading file!");
            }
        });
    }
}

解决方案

You encode the file in whatever chunks come from the disk I/O:

        int step = (int) (bytesLeft > 150000 ? 150000 : bytesLeft);
        byte[] buffer = new byte[step];
        fileStream.read(buffer);
        buffer = cipher.encryptFile(buffer, key);

But you decode the file in whatever chunks come from the network I/O:

        bytesRead = input.read(buffer);
        if (bytesRead >= 0) {
            buffer = cipher.decryptFile(buffer, key);
            outStream.write(buffer, 0, bytesRead);
            counter += bytesRead;
        }

These chunks are likely to disagree. The disk I/O may always give you full chunks (lucky for you), but the network I/O will likely give you packet-sized chunks (1500 bytes minus header).

The cipher should get an offset into the already encoded/decoded data (or encode/decode everything at once), and use that to shift the key appropriately, or this may happen:

original: ...LOREM IPSUM...
key     : ...abCde abCde...
encoded : ...MQUIR JRVYR...
key     : ...abCde Cdeab... <<note the key got shifted
decoded : ...LOREM GNQXP... <<output wrong after the first chunk.

Since the packet data size is (for Ethernet-sized TCP/IP packets) aligned at four bytes, a key of length four is likely to be always aligned.


another issue is that you are ignoring the number of bytes read from disk when uploading the file. While disk I/O is likely to always give you full-sized chunks (the file's likely to be memory-mapped or the underlying native API does provide this guarantee), nothing's taken for granted. Always use the amount of bytes actually read: bytesRead = fileStream.read(buffer);

这篇关于使用java中的vigenere加密加密字节数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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