加密和解密Java中的密码

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

Encrypting and Decrypting password in java

问题

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Key;
import javax.crypto.Cipher;
import java.util.Scanner;

public class Password {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String password = sc.nextLine();
        KeyPair keyPair = RSAKeyPair.keyPairRSA();
        Key publicKey = keyPair.getPublic();
        Key privateKey = keyPair.getPrivate();
        System.out.println("Original: " + password);
        byte[] encrypted = RSAEncryptDecrypt.encrypt(password, privateKey);
        System.out.println("Encrypted: " + new String(encrypted));
        byte[] decrypted = RSAEncryptDecrypt.decrypt(encrypted, publicKey);
        System.out.println("Decrypted: " + new String(decrypted));
    }
}

final class RSAConstants {
    private RSAConstants() {
    }
    public static final String ALGORITHM = "RSA";
    public static final int ALGORITHM_BITS = 2048;
}

class RSAKeyPair {
    public static KeyPair keyPairRSA() {
        KeyPairGenerator generator = null;
        try {
            generator = KeyPairGenerator.getInstance(RSAConstants.ALGORITHM);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (generator != null) {
            generator.initialize(RSAConstants.ALGORITHM_BITS);
            KeyPair keyPair = generator.genKeyPair();
            return keyPair;
        }
        return null;
    }
}

class RSAEncryptDecrypt {
    public static byte[] encrypt(String original, Key privateKey) {
        if (original != null && privateKey != null) {
            byte[] bs = original.getBytes();
            byte[] encData = convert(bs, privateKey, Cipher.ENCRYPT_MODE);
            return encData;
        }
        return null;
    }
    public static byte[] decrypt(byte[] encrypted, Key publicKey) {
        if (encrypted != null && publicKey != null) {
            byte[] decData = convert(encrypted, publicKey, Cipher.DECRYPT_MODE);
            return decData;
        }
        return null;
    }
    private static byte[] convert(byte[] data, Key key, int mode) {
        try {
            Cipher cipher = Cipher.getInstance(RSAConstants.ALGORITHM);
            cipher.init(mode, key);
            byte[] newData = cipher.doFinal(data);
            return newData;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

Input:

InterstellarGalactica

All goes smooth except for the result of Encrypted Password
Resulting below

Original: InterstellarGalactica
Encrypted: [Encrypted Data]
Decrypted: InterstellarGalactica

Why does it become a meaningless character?

Is there anything wrong with my code?

Can you explain how to do it in the proper way (if there is)?

Thanks in advance.


<details>
<summary>英文:</summary>
Im Trying to do my homework to create a class called Password that implements the Encryptable interface.
Im trying using RSA Algorythm.
I use some RSA code references from the Google and resulting my code below.

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Key;
import java.util.Arrays;
import javax.crypto.Cipher;
import java.util.Scanner;
public class Password
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
String password = sc.nextLine();
KeyPair keyPair = RSAKeyPair.keyPairRSA();
Key publicKey = keyPair.getPublic();
Key privateKey = keyPair.getPrivate();
System.out.println("Original: " + password);
byte[] encrypted = RSAEncryptDecrypt.encrypt(password, privateKey);
System.out.println("Encrypted: " + new String(encrypted));
byte[] decrypted = RSAEncryptDecrypt.decrypt(encrypted, publicKey);
System.out.println("Decrypted: " + new String(decrypted));
}
}
final class RSAConstants {
private RSAConstants() {
}
public static final String ALGORITHM = "RSA";
public static final int ALGORITHM_BITS = 2048;
}
class RSAKeyPair {
public static KeyPair keyPairRSA() {
KeyPairGenerator generator = null;
try {
generator = KeyPairGenerator.getInstance(RSAConstants.ALGORITHM);
} catch (Exception e) {
e.printStackTrace();
}
if (generator != null) {
generator.initialize(RSAConstants.ALGORITHM_BITS);
KeyPair keyPair = generator.genKeyPair();
return keyPair;
}
return null;
}
}

class RSAEncryptDecrypt {
public static byte[] encrypt(String original, Key privateKey) {
if (original != null && privateKey != null) {
byte[] bs = original.getBytes();
byte[] encData = convert(bs, privateKey, Cipher.ENCRYPT_MODE);
return encData;
}
return null;
}
public static byte[] decrypt(byte[] encrypted, Key publicKey) {
if (encrypted != null && publicKey != null) {
byte[] decData = convert(encrypted, publicKey, Cipher.DECRYPT_MODE);
return decData;
}
return null;
}
private static byte[] convert(byte[] data, Key key, int mode) {
try {
Cipher cipher = Cipher.getInstance(RSAConstants.ALGORITHM);
cipher.init(mode, key);
byte[] newData = cipher.doFinal(data);
return newData;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}

My Input is:
`InterstellarGalactica
`
All goes smooth except for the result of Encrypted Password
Resulting below

Original: InterstellarGalactica
Encrypted: Sªë/H?ù,X?U4??A???ìñáQ
÷? ?7??d?'å?Ñ¡w °??? Pè???«{?D ÷??cB???'É »???qªîÉDë??~hb??z8?çÿ?hí?{mè?{*îèGê??WÅ{x??ï.5¼?úü;e??G?-F?shèn?FI
áh`UƒIàB!?åäô+ D<&"?)?????ß!??3ä?¬???â???<?¬Ü?{ @ó12B?òt?ƒòÆr²Ä·oHQ?ë?«ú?°?î? ?Äy?:X^<?
&:ryb?¼
Decrypted: InterstellarGalactica

Why do it is became a meaningless character?
Is there anything wrong with my code?
Can you explain how to do it in proper way(if there is)?
Thanks in advance.
</details>
# 答案1
**得分**: 1
你正在错误地使用RSA:
在RSA中,你使用公钥进行加密,使用私钥进行解密。
然而,你却使用私钥进行加密,使用公钥进行解密:
```java
byte[] encrypted = RSAEncryptDecrypt.encrypt(password, privateKey);
byte[] decrypted = RSAEncryptDecrypt.decrypt(encrypted, publicKey);

另外,请不要将包含二进制数据的byte[]转换为字符串。如果你想要打印二进制数据,可以将其转换为十六进制或base64字符串。或者如果你想要将其打印为数字,可以使用BigInteger

// 输出Base64编码
System.out.println(java.util.Base64.getEncoder().encode(encrypted));

// 输出十六进制(使用Apache Commons Codec库)
System.out.println(org.apache.commons.codec.binary.Hex.encodeHexString(encrypted));

// 输出不使用外部库的十六进制
System.out.println(new java.math.BigInteger(1, encrypted).toString(16));

// 输出作为大数(用于手动RSA计算)
System.out.println(new java.math.BigInteger(1, encrypted));
英文:

You are using RSA in the wrong way:

In RSA you use the public key for encryption and the private key for decryption.

You however use the private key for encryption and the public key for decryption:

    byte[] encrypted = RSAEncryptDecrypt.encrypt(password, privateKey);
byte[] decrypted = RSAEncryptDecrypt.decrypt(encrypted, publicKey);

Additionally please never convert a byte[] that contains binary data to String. If you want to print binary data convert it for example to a hexadecimal or base64 String instead. Or if you want to print it as a number use BigInteger.

// output Base64 encoded    
System.out.println(java.util.Base64.getEncoder().encode(encrypted));
// out hexadecimal (uses Apache commons codec library
System.out.println(org.apache.commons.codec.binary.Hex.encodeHexString(encrypted));
// out hexadecimal without external library)    
System.out.println(new java.math.BigInteger(1, encrypted).toString(16))
// Output as large number (useful for manual RSA calculations)
System.out.println(new java.math.BigInteger(1, encrypted));

huangapple
  • 本文由 发表于 2020年4月11日 13:40:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/61152582.html
匿名

发表评论

匿名网友

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

确定