KeyGenerator not available – Java issue

huangapple go评论67阅读模式
英文:

KeyGenerator not available - Java issue

问题

在你提供的代码和POM文件中,你遇到了一些问题,主要是与密钥生成和加密算法相关的问题。以下是你的代码中存在的问题的中文翻译:

  1. 问题描述:
    "So I am doing a small project and getting extremely frusterated. Ive tried inputting different algorithms for the KeyGenerator and different key sizes but with no luck. Could someone please help me out?"

    问题描述:
    "我正在进行一个小项目,但感到非常沮丧。我尝试使用不同的KeyGenerator算法和不同的密钥大小,但都没有成功。有人可以帮帮我吗?"

  2. 错误信息1:
    "If I put simply "AES" - I get ECB Mode can not use IV"

    错误信息1:
    "如果我只输入"AES" - 我会得到错误消息:ECB模式不能使用初始化向量(IV)。"

  3. 错误信息2:
    "and if I put "AES/CBC/PKCS5PADDING" - I get KeyGenerator not available"

    错误信息2:
    "如果我输入"AES/CBC/PKCS5PADDING" - 我会得到错误消息:KeyGenerator不可用。"

以上是你提供的问题和错误消息的中文翻译,希望对你理解代码问题有所帮助。如果你需要进一步的解决方案,请告诉我。

英文:

So I am doing a small project and getting extremely frusterated. Ive tried inputting different algorithms for the KeyGenerator and different key sizes but with no luck. Could someone please help me out?
If I put simply "AES" - I get ECB Mode can not use IV
and if I put "AES/CBC/PKCS5PADDING" - I get KeyGenerator not available

@SpringBootApplication
public class SslServerApplication {

	private static final String ALGORITHM = "AES/CBC/PKCS5PADDING";
	private static final int KEY_SIZE = 192;

	public static void main(String[] args) throws Exception {
	    SecretKey key = generateKey();
	    String message = "Hello, Professor Conlan!";

	    byte[] encrypted = encrypt(message, key);
	    byte[] hash = hash(encrypted);

	    System.out.println("Hash: " + bytesToHex(hash));

	    boolean verified = verifyChecksum(hash, encrypted, key);
	    System.out.println("Checksum verified: " + verified);
	}
	//generates secret key
	private static SecretKey generateKey() throws NoSuchAlgorithmException {
	    KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);
	    keyGenerator.init(KEY_SIZE);
	    return keyGenerator.generateKey();
	}
	//encrypts secret key key
	static byte[] encrypt(String message, SecretKey key) throws Exception {
	    Cipher cipher = Cipher.getInstance(ALGORITHM);
	    byte[] iv = new byte[cipher.getBlockSize()];
	    SecureRandom random = new SecureRandom();
	    random.nextBytes(iv);
	    cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
	    return cipher.doFinal(message.getBytes(StandardCharsets.UTF_8));
	}

	static byte[] hash(byte[] message) throws Exception {
	    MessageDigest md = MessageDigest.getInstance("SHA-256");
	    return md.digest(message);
	}

	private static boolean verifyChecksum(byte[] checksum, byte[] message, SecretKey key) throws Exception {
	    byte[] hash = hash(decrypt(message, key));
	    return MessageDigest.isEqual(hash, checksum);
	}
	//decrypts the encrypted secret key
	static byte[] decrypt(byte[] message, SecretKey key) throws Exception {
	    Cipher cipher = Cipher.getInstance(ALGORITHM);
	    byte[] iv = Arrays.copyOfRange(message, 0, cipher.getBlockSize());
	    cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
	    return cipher.doFinal(Arrays.copyOfRange(message, cipher.getBlockSize(), message.length));
	}

	static String bytesToHex(byte[] bytes) {
	    StringBuilder result = new StringBuilder();
	    for (byte b : bytes) {
	        result.append(String.format("%02x", b));
	    }
	    return result.toString();
	}
}

EDIT: This is my POM file

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.2.4.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.snhu</groupId>
	<artifactId>ssl-server</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>ssl-server</name>
	<description>ssl-server skeleton for CS-305</description>
	
	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-rest</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
			<plugin>
            	<groupId>org.owasp</groupId>
            	<artifactId>dependency-check-maven</artifactId>
            	<version>5.3.0</version>
            	<configuration>
            	 <outputDirectory default-value="C:\Users\Shawn\Documents\M7 Folder"/>
            	</configuration>
            	
            	<executions>
                  <execution>
                      <goals>
                          <goal>check</goal>
                      </goals>
                  </execution>
              </executions>
            </plugin>
		</plugins>
	</build>

</project>

答案1

得分: 2

"AES/CBC/PKCS5PADDING" 是一个 Cipher 规范,由以下部分组成:


对于 KeyGenerator,只有算法本身是相关的 (KeyGenerator 算法),在调用 KeyGenerator.getInstance() 时,必须只指定算法。

KeyGenerator.getInstance("AES") 将适用于 KeyGenerator

注意:对于 Cipher,仍然必须使用 "AES/CBC/PKCS5PADDING"!否则,您将获得特定于提供程序的 Cipher

转换的形式为:

  • "算法/模式/填充" 或
  • "算法"

(在后一种情况下,将使用提供程序特定的默认模式和填充方案的默认值)。

英文:

"AES/CBC/PKCS5PADDING" is a Cipher specification consisting of


For the KeyGenerator only the algorithm itself is relevant (KeyGenerator Algorithms) and you must only specify the algorithm when calling KeyGenerator.getInstance().

KeyGenerator.getInstance("AES") will work for the KeyGenerator.

Note: For the Cipher you still must use "AES/CBC/PKCS5PADDING"! Otherwise you will get a provider-specific Cipher:

> A transformation is of the form:
>
> * "algorithm/mode/padding" or
> * "algorithm"
>
> (in the latter case, provider-specific default values for the mode and padding scheme are used).

答案2

得分: 1

你不能在KeyGenerator算法和Cipher算法中使用相同的值。

以下是KeyGenerator算法的合法值。你的值AES/CBC/PKCS5PADDING并不在其中,正如Thomas的回答所正确指出的:

  • AES
  • ARCFOUR
  • Blowfish
  • DES
  • DESede
  • HmacMD5
  • HmacSHA1 HmacSHA256 HmacSHA384 HmacSHA512
  • RC2

以下是Java实现必须支持的Cipher算法。你的值AES/CBC/PKCS5PADDING在此可以使用(如果你的代码执行到足够远的程度):

  • AES/CBC/NoPadding(128)
  • AES/CBC/PKCS5Padding(128)
  • AES/ECB/NoPadding(128)
  • AES/ECB/PKCS5Padding(128)
  • DES/CBC/NoPadding(56)
  • DES/CBC/PKCS5Padding(56)
  • DES/ECB/NoPadding(56)
  • DES/ECB/PKCS5Padding(56)
  • DESede/CBC/NoPadding(168)
  • DESede/CBC/PKCS5Padding(168)
  • DESede/ECB/NoPadding(168)
  • DESede/ECB/PKCS5Padding(168)
  • RSA/ECB/PKCS1Padding(1024, 2048)
  • RSA/ECB/OAEPWithSHA-1AndMGF1Padding(1024, 2048)
  • RSA/ECB/OAEPWithSHA-256AndMGF1Padding(1024, 2048)

以下是“有效”的代码。你的代码存在其他问题。

@SpringBootApplication
public class SslServerApplication {
    private static final String KEYGENERATOR_ALGORITHM = "AES";
    private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS5PADDING";
    private static final int KEY_SIZE = 192;

    public static void main(String[] args) throws Exception {
        SecretKey key = generateKey();
        String message = "Hello, Professor Conlan!";

        byte[] encrypted = encrypt(message, key);
        byte[] hash = hash(encrypted);

        System.out.println("Hash: " + bytesToHex(hash));

        boolean verified = verifyChecksum(hash, encrypted, key);
        System.out.println("Checksum verified: " + verified);

        String decrypted = new String(decrypt(encrypted, key));
        System.out.println("Decrypted messaged: " + decrypted);
    }

    // 生成密钥
    private static SecretKey generateKey() throws NoSuchAlgorithmException {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(KEYGENERATOR_ALGORITHM);
        keyGenerator.init(KEY_SIZE);
        return keyGenerator.generateKey();
    }

    // 加密消息
    static byte[] encrypt(String message, SecretKey key) throws Exception {
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        byte[] iv = new byte[cipher.getBlockSize()];
        SecureRandom random = new SecureRandom();
        random.nextBytes(iv);
        cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
        return cipher.doFinal(message.getBytes(StandardCharsets.UTF_8));
    }

    static byte[] hash(byte[] message) throws Exception {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        return md.digest(message);
    }

    private static boolean verifyChecksum(byte[] checksum, byte[] message, SecretKey key) throws Exception {
        byte[] hash = hash(decrypt(message, key));
        return MessageDigest.isEqual(hash, checksum);
    }

    // 解密加密的消息
    static byte[] decrypt(byte[] message, SecretKey key) throws Exception {
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        byte[] iv = Arrays.copyOfRange(message, 0, cipher.getBlockSize());
        cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
        return cipher.doFinal(Arrays.copyOfRange(message, cipher.getBlockSize(), message.length));
    }

    static String bytesToHex(byte[] bytes) {
        StringBuilder result = new StringBuilder();
        for (byte b : bytes) {
            result.append(String.format("%02x", b));
        }
        return result.toString();
    }
}
英文:

You cannot use the same value for the KeyGenerator algorithm and the Cipher algorithm.

These are the legal values of KeyGenerator algorithm. Your value of AES/CBC/PKCS5PADDING is not among them as Thomas's answer correctly indicates.

AES
ARCFOUR
Blowfish
DES
DESede
HmacMD5
HmacSHA1 HmacSHA256 HmacSHA384 HmacSHA512
RC2

The following are the Cipher algorithms that must be supported by Java implementations. Your value of AES/CBC/PKCS5PADDING will work here (if your code gets far enough.

AES/CBC/NoPadding (128)
AES/CBC/PKCS5Padding (128)
AES/ECB/NoPadding (128)
AES/ECB/PKCS5Padding (128)
DES/CBC/NoPadding (56)
DES/CBC/PKCS5Padding (56)
DES/ECB/NoPadding (56)
DES/ECB/PKCS5Padding (56)
DESede/CBC/NoPadding (168)
DESede/CBC/PKCS5Padding (168)
DESede/ECB/NoPadding (168)
DESede/ECB/PKCS5Padding (168)
RSA/ECB/PKCS1Padding (1024, 2048)
RSA/ECB/OAEPWithSHA-1AndMGF1Padding (1024, 2048)
RSA/ECB/OAEPWithSHA-256AndMGF1Padding (1024, 2048)

The following is code that 'works'. Your code has other issues.

@SpringBootApplication
public class SslServerApplication {
private static final String KEYGENERATOR_ALGORITHM = "AES";
private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS5PADDING";
private static final int KEY_SIZE = 192;
public static void main(String[] args) throws Exception {
SecretKey key = generateKey();
String message = "Hello, Professor Conlan!";
byte[] encrypted = encrypt(message, key);
byte[] hash = hash(encrypted);
System.out.println("Hash: " + bytesToHex(hash));
boolean verified = verifyChecksum(hash, encrypted, key);
System.out.println("Checksum verified: " + verified);
String decrypted =  new String(decrypt(encrypted, key));
System.out.println("Decrypted messaged: " + decrypted);
}
//generates secret key
private static SecretKey generateKey() throws NoSuchAlgorithmException {
KeyGenerator keyGenerator = KeyGenerator.getInstance(KEYGENERATOR_ALGORITHM);
keyGenerator.init(KEY_SIZE);
return keyGenerator.generateKey();
}
//encrypts secret key key
static byte[] encrypt(String message, SecretKey key) throws Exception {
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
byte[] iv = new byte[cipher.getBlockSize()];
SecureRandom random = new SecureRandom();
random.nextBytes(iv);
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
return cipher.doFinal(message.getBytes(StandardCharsets.UTF_8));
}
static byte[] hash(byte[] message) throws Exception {
MessageDigest md = MessageDigest.getInstance("SHA-256");
return md.digest(message);
}
private static boolean verifyChecksum(byte[] checksum, byte[] message, SecretKey key) throws Exception {
byte[] hash = hash(decrypt(message, key));
return MessageDigest.isEqual(hash, checksum);
}
//decrypts the encrypted secret key
static byte[] decrypt(byte[] message, SecretKey key) throws Exception {
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
byte[] iv = Arrays.copyOfRange(message, 0, cipher.getBlockSize());
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
return cipher.doFinal(Arrays.copyOfRange(message, cipher.getBlockSize(), message.length));
}
static String bytesToHex(byte[] bytes) {
StringBuilder result = new StringBuilder();
for (byte b : bytes) {
result.append(String.format("%02x", b));
}
return result.toString();
}

huangapple
  • 本文由 发表于 2023年2月19日 18:29:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/75499462.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定