Java 使用配置动态创建密码:需要哪些参数?

Java 使用配置动态创建密码:需要哪些参数?,java,encryption,cryptoapi,Java,Encryption,Cryptoapi,Java使用Cipher类作为特定密码实现的抽象。在我的项目中,我主要使用对称块密码(AES、Twofish、3DES等),我正在寻找一种方法来动态创建/初始化任何可能的对称块密码(使用XML配置),因为我希望使加密可配置 示例: 将翻译为: // Create secretKey using 'keysize' ... if (encryption.isUnlimitedCrypto()) { Encryption.enableUnlimitedCrypto(); } Cipher

Java使用
Cipher
类作为特定密码实现的抽象。在我的项目中,我主要使用对称块密码(AES、Twofish、3DES等),我正在寻找一种方法来动态创建/初始化任何可能的对称块密码(使用XML配置),因为我希望使加密可配置

示例:

将翻译为:

// Create secretKey using 'keysize' ...

if (encryption.isUnlimitedCrypto()) {
    Encryption.enableUnlimitedCrypto();
}

Cipher cipher = Cipher.getInstance(encryption.getCipherStr(), Encryption.PROVIDER);

if (encryption.isIvNeeded()) {
    byte[] iv = ... 
    cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(iv));
}
else {
    cipher.init(Cipher.ENCRYPT_MODE, secretKey);
}
我的问题是:在Java中实例化任何对称分组密码需要哪些参数?

参数(已确定):

  • Cipher String:Cipher.getInstance(..)的字符串,例如AES/CBC/PKCSPadding
  • 密钥大小:密钥生成的密钥大小(或PBE密钥派生函数)
  • 需要IV:表示是否需要IV,例如CBC和GCM模式为“真”,但ECB不需要
  • IV大小:表示IV的大小(现在我假设IV大小=键大小,对吗?)
  • 需要无限强度:指示是否需要启用无限强度策略文件
  • 其他人
原始来源/项目:

  • 实施:
  • 测试中的预期用途:

除ECB以外的所有模式都需要IV。IV始终等于密码的块大小(AES为16字节,3DE为8字节)<代码>ECB模式在使用同一密钥加密多个明文块时不安全,如果希望确保机密性,则不应允许使用该模式

使用的算法将指定所需的密钥大小。例如,如果使用Java的标准加密API,AES需要为192和256安装128、192或256个无限强度策略。无限强度策略不是可以用代码切换的,它必须安装在最终用户JRE中

如果您关心传输中数据的安全性(而且这个项目有真正的安全需求),那么我不能强烈要求您使用SSL/TLS来实现这一点。创建一个安全的密码系统很困难,批量加密(即AES、3DES等对称密码)本身不足以确保安全性。您还需要加密功能强大的随机数据源、安全的密钥交换过程和完整性验证。如果不确保完整性(通常通过使用MAC功能提供),则很难提供机密性。在实现安全密码系统时,有一些陷阱,例如确保使用不同的密钥来加密和MAC,正确地验证MACS,以不使用攻击向量来创建定时攻击向量,确保完整性,从而不创建填充oracle等。 正如您所见,保护传输的数据有很多可移动的部分,从头开始可能会导致错误选择或错误配置的加密原语带来的漏洞。这就是为什么经常推荐TLS

下面是由两个套接字建立的匿名(无身份验证)TLS会话的示例。此示例不安全,因为双方都不对另一方进行身份验证,但建立了机密性和完整性。我在示例中使用这个不安全的密码套件的原因是,不用进入密钥库和信任库(用于身份验证部分),就可以很容易地演示TLS的使用

正在使用的密码套件是TLS_ECDH_anon_WITH_AES_128_CBC_SHA,由于上述缺乏身份验证,通常默认情况下不会启用该套件。下面我将分解这个密码套件

  • TLS-此密码套件由TLS标准引入
  • 密钥协商使用ECDH_anon-Elipic Cuve-Diffie-Hellman算法,但密钥协商未经身份验证
  • AES_128_CBC-在密码块链接模式下具有128位密钥长度的高级加密标准用于批量加密
  • SHA安全哈希算法用于确保加密数据的完整性
下面是一个例子

package com.stackoverflow._19505091;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;

public class AnonTLSExample {

    public static void main(String[] args) throws Exception {

        /* No certs for this example so we are using ECDH_anon exchange. */
        String[] cipherSuites = {"TLS_ECDH_anon_WITH_AES_128_CBC_SHA"};
        SSLContext sslContext = SSLContext.getInstance("TLSv1.2");

        /* No certificates, use default secure random source.
         * If we were using authentication (and you should in a real
         * system), this is where we would load 
         * keystores and truststores. */
        sslContext.init(null, null, null);

        /* Create server socket. */
        SSLServerSocket ss = (SSLServerSocket) sslContext.getServerSocketFactory().createServerSocket(12345);
        ss.setEnabledCipherSuites(cipherSuites);

        /*
         * Normally when authentication is used only the client authenticates
         * the server. If you want the server to also authenticate the client
         * set this to true. This will establish bidirectional trust in the session.
         */
        ss.setWantClientAuth(false);

        /* Start server thread. */
        new Thread(new Server(ss), "ServerThread").start();

        /* Create client socket. */
        SSLSocket s = (SSLSocket) sslContext.getSocketFactory().createSocket();
        s.setEnabledCipherSuites(cipherSuites);

        /* Connect to server. */
        System.out.println("Client: Connecting...");
        s.connect(new InetSocketAddress("127.0.0.1", 12345));
        System.out.println("Client: Connected");

        /* Print out some TLS info for this connection. */
        SSLSession session = s.getSession();
        System.out.println("Client: Session secured with P: " + session.getProtocol() + " CS: " + session.getCipherSuite());

        /* Send the secret message. */
        DataOutputStream dos = new DataOutputStream(s.getOutputStream());
        String message = "Secret Message.";
        System.out.println("Client: Sending: " + message);
        dos.writeUTF(message);

        /* Wait for server to close stream. */
        System.out.println("Client: Waiting for server to close...");
        s.getInputStream().read();

        /* Close client socket. */
        s.close();
        System.out.println("Client: Done.");
    }


}

class Server implements Runnable {

    private final ServerSocket ss;

    public Server(ServerSocket ss){
        this.ss = ss;
    }

    @Override
    public void run() {
        try{
         /* Wait for client to connect. */
         System.out.println("Server: Waiting for connection...");
         Socket s = ss.accept();
         System.out.println("Server: Connected.");

         /* Read secret message. */
         DataInputStream dis = new DataInputStream(s.getInputStream());
         String message = dis.readUTF();
         System.out.println("Server: Received Message: " + message);

         /* Close our sockets. */
         s.close();
         ss.close();
         System.out.println("Server: Done.");
        }catch(Exception e){
            e.printStackTrace();
        }

    }
}

IV尺寸=关键尺寸?不IV size=块大小,除非模式状态的说明另有说明谢谢您提供有关IV(IV size=块大小)的信息,ECB是唯一没有IV的模式。我的应用程序对传输安全没有影响,因此SSL/TLS不受我的关注。使用反射可以编程启用无限强度:不幸的是,这个答案并不能完全回答我的问题。我仍然不知道给定的参数是否完全识别密码(以便以编程方式创建密码)解决了它:这里实现:这里使用: