1

当我运行以下代码时,解密长度与原始长度不同。所以无法读取音频。

我收到此错误:javax.sound.sampled.UnsupportedAudioFileException: could not get audio input stream from input stream

at javax.sound.sampled.AudioSystem.getAudioInputStream(AudioSystem.java:1119)
at MainClass.main(MainClass.java:119)

我的代码在这里:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;

public class MainClass {
public static final int SIZE = 1024;

private BigInteger p, q, n, totient, e, d;
private Random rnd = new Random();

public MainClass() {

    p = new BigInteger(1024, 10, new Random());
    do {
        q = new BigInteger(1024, 10, new Random());
    } while (p.equals(q));

    n = p.multiply(q);

    totient = (p.subtract(BigInteger.ONE)).multiply(q
            .subtract(BigInteger.ONE));

    // System.out.println(p+"\n"+q+"\n"+n+"\n"+totient);
}

public BigInteger getMod() {
    d = e.modInverse(totient);
    // System.out.println("d="+d);
    return d;
}

public BigInteger getE() {
    do {
        e = new BigInteger(SIZE, rnd);
    } while (!e.gcd(totient).equals(BigInteger.ONE)
            || !(e.compareTo(totient) < 0));
    return e;
}

public String encrypt(String msg) {
    BigInteger ciphertext = new BigInteger(msg.getBytes());
    String cipher = (ciphertext).modPow(getE(), getN()).toString();
    return cipher;
}

public String decrypt(String msg) {
    byte[] decryptMsg = (new BigInteger(msg)).modPow(getMod(), getN())
            .toByteArray();
    String plain = new String(decryptMsg);
    return plain;
}

public BigInteger getN() {
    return n;
}

public static void main(String[] args) {

    try {
        List<String> ori = new ArrayList<String>();
        List<String> st1 = new ArrayList<String>();
        List<String> st2 = new ArrayList<String>();
        String s2;

        MainClass mc = new MainClass();
        // StringHelper sh = new StringHelper();
        byte[] input;
        final ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
        // final AudioFileFormat.Type [] types =
        // AudioSystem.getAudioFileTypes();
        final String PATH = "C:\\Users\\Rahul\\Desktop\\adios.wav";
        final AudioInputStream audioInputStream = AudioSystem
                .getAudioInputStream(new File(PATH));

        AudioSystem.write(audioInputStream, AudioFileFormat.Type.WAVE,
                byteOut);
        audioInputStream.close();
        byteOut.close();
        input = ((ByteArrayOutputStream) byteOut).toByteArray();
        System.out.println(input.length);

        input.toString();
        String s = new String(input);
        System.out.println("Original " + s.length() + "\n");

        int i = 0;
        for (i = 0; i + 255 < s.length(); i = i + 256) {
            ori.add(s.substring(i, i + 255));
        }
        ori.add(s.substring(i - 256, s.length() - 1));
        // System.out.println(s.length());
        for (i = 0; i < ori.size(); i++) {
            st1.add(mc.encrypt(ori.get(i)));
        }
        // String s1 = mc.encrypt(s.substring(0, 500));

        // System.out.println("Cipher Text");
        // System.out.println(s1.length()+ "\n"+s1);
        for (i = 0; i < st1.size(); i++) {
            st2.add(mc.decrypt(st1.get(i)));
        }
        // String s2 = mc.decrypt(s1);
        StringBuffer sb = new StringBuffer();
        for (i = 0; i < st2.size(); i++) {
            sb.append(st2.get(i));
        }
        s2 = sb.toString();
        System.out.println("Decrypt" + s2.length() + "\n");
        byte[] output = s2.getBytes();
        ByteArrayInputStream oInstream = new ByteArrayInputStream(output);
        AudioInputStream oAIS = AudioSystem.getAudioInputStream(oInstream);
        AudioSystem.write(oAIS, AudioFileFormat.Type.WAVE, new File(
                "E:\\decrypted.wav"));
        oAIS.close();
        oInstream.close();
    } catch (Exception e) {
        e.printStackTrace();
    }

}

}

有什么帮助吗??

4

2 回答 2

5

这段代码在很多方面都被破坏了:

  1. 您正在使用不安全的 PRNG
  2. p并且q应该是素数
  3. 您没有使用填充。RSA需要填充,最好是OAEP
  4. 你对定时攻击持开放态度
  5. RSA 一次只能加密几个字节。在实践中,我们很少使用 RSA 加密实际数据。它很,它增加了密文的大小,没有标准化的模式,......
  6. 滥用字符串。您从stringto的转换BigInteger是胡说八道。你根本不应该使用字符串,你应该直接使用二进制数据。
  7. 这不是一个真正的问题,但在实践中,我们选择e大于 2 的小素数,例如 3 或 65537。这会显着加快公钥操作。

你应该怎么做:

  1. 使用 Java 内置的 RSA
  2. 生成一个新的随机 AES 密钥并使用 RSA 对其进行加密
  3. 在认证模式下使用 AES 加密实际数据(例如 AES-GCM)
  4. 连接 2. 和 3. 的结果。
于 2012-12-06T10:20:41.293 回答
3

您似乎正在尝试重新发明轮子,同时使其符合讨价还价。Java 有一个内置的加密 API,我强烈建议您使用它。而且您还需要完全掌握在哪里使用哪种加密。

除了您的实现之外,您遇到的一个关键问题是 RSA 是为传递非常小的数据而设计的——本质上,它是另一种算法的密钥,实际上用于执行主要数据的加密。或者换一种说法,如果这有帮助:将 RSA 本质上视为一种密钥传递方案,而不是“加密”算法本身。

你应该:

我也非常鼓励您通读我的教程和其他人的教程,以真正尝试并了解密码学正在发生的事情。这是一个相当复杂的领域,在没有很好地理解基本概念的情况下“潜入”可能会导致您编写不安全的代码。

于 2012-12-06T10:29:28.610 回答