gpt4 book ai didi

java - 使用配置 : What parameters are necessary? 动态创建密码

转载 作者:行者123 更新时间:2023-11-30 09:16:14 27 4
gpt4 key购买 nike

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

示例: <transformer type="cipher" cipher="AES/GCM/NoPadding" keysize="256" iv="true" unlimitedstrength="true" />

将被翻译成:

// 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.getInstance(..) 的字符串,例如AES/CBC/PKCSPadding
  • key 大小: key 生成(或 PBE key 派生函数)的 key 大小
  • 需要 IV:表示是否需要 IV,例如CBC 和 GCM 模式为“true”,但 ECB 不为“true”
  • IV 大小:指示 IV 的大小(现在我假设 IV 大小 = key 大小,对吗?)
  • Unlimited strength needed:表示是否需要启用unlimited strength策略文件
  • 其他人?

原始来源/项目:

最佳答案

ECB 以外的所有模式都需要 IV。 IV 将始终等于密码的 block 大小(AES 为 16 个字节,3DES 为 8 个字节)。 ECB 模式在使用相同 key 加密超过 1 个明文 block 时是不安全的,如果您希望确保 secret 性,则不应允许该模式。

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

如果您关心传输中数据的安全(并且该项目具有真正的安全需求),我强烈建议您为此使用 SSL/TLS。创建一个安全的密码系统很难,批量加密(即对称密码,如 AES、3DES)本身不足以确保安全。您还需要加密强大的随机数据源、安全的 key 交换过程和完整性验证。如果不确保通常通过使用 MAC 功能提供的完整性,则很难提供 secret 信息。实现安全加密系统时要避免所有陷阱,例如确保对密码和 MAC 使用不同的 key 、正确验证 MAC 以免创建时序攻击 vector 、使用适当的随机生成器、确保完整性以免创建填充 oracle 等

如您所见,保护传输的数据有很多 Activity 部分,从头开始做可能会导致错误选择或错误配置的加密原语引入漏洞。这就是经常推荐使用 TLS 的原因。

下面是由两个套接字建立的匿名(无身份验证)TLS session 的示例。这个例子是不安全的,因为双方都没有验证对方,但是建立了 secret 性和完整性。我在示例中使用此不安全密码套件的原因是无需进入 keystore 和信任库(用于身份验证部分)即可轻松演示 TLS 用法

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

  • TLS - 此密码套件由 TLS 标准引入。
  • ECDH_anon - Eliptic Cuve Diffie-Hellman 算法用于 key 协商,但 key 协商未经过身份验证。
  • AES_128_CBC - 在密码 block 链接模式下具有 128 位 key 长度的高级加密标准用于批量加密。
  • 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();
}

}
}

关于java - 使用配置 : What parameters are necessary? 动态创建密码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19505091/

27 4 0