簡體   English   中英

我如何擁有自己的公鑰來加密數據?

[英]How do I have my own public key to encrypt data?

我有一個用戶 class,一個實體,它必須使用大小為 2048 的非對稱密鑰 (RSA) 以加密形式寫入用戶名和 email。

信息將使用客戶的公鑰加密,他將使用他的私鑰解密。

@Entity
public class Usuario implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String nome;

    private String email;

    @JsonBackReference
    @ManyToMany
    @JoinTable(name = "USUARIO_DIGITO", joinColumns = @JoinColumn(name = "usuario_id"), inverseJoinColumns = @JoinColumn(name = "digito_id"))
    private Set<DigitoUnico> resultadosDigitoUnico;
    
    ....
    getters and setters
    
}

在用戶服務中,我調用了為加密和解密創建的方法。

@Service
public class UsuarioService implements IUsuarioService {

    @Autowired
    private IUsuarioRepository usuarioRepository;   
    
....

    public Usuario adicionar(Usuario usuario) {
        
        usuario.setId(null);
        usuario.setResultadosDigitoUnico(null);
        
        try {
            return usuarioRepository.save(encriptarDadosUsuario(usuario));
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
    
        private Usuario encriptarDadosUsuario(Usuario usuario) throws Exception {
        usuario.setEmail(EncriptaDadosUsuario.encriptar(usuario.getEmail(), EncriptaDadosUsuario.gerarParDeChaves().getPublic()));
        usuario.setNome(EncriptaDadosUsuario.encriptar(usuario.getNome(), EncriptaDadosUsuario.gerarParDeChaves().getPublic()));
        return usuario;
    }
    
    private Usuario decriptarDadosUsuario(Usuario usuario) throws Exception{
        usuario.setEmail(EncriptaDadosUsuario.decriptar(usuario.getEmail(),EncriptaDadosUsuario.gerarParDeChaves().getPrivate()));
        usuario.setNome(EncriptaDadosUsuario.decriptar(usuario.getNome(),EncriptaDadosUsuario.gerarParDeChaves().getPrivate()));
        return usuario;
    }
}

但是,我必須創建一個端點來將此用戶的公鑰發送到客戶端以進行加密。

我怎樣才能擁有我的公鑰,並將其用於此加密和解密?

下面我class來加密:

public class EncriptaDadosUsuario {

    public static KeyPair gerarParDeChaves() throws Exception {
        KeyPairGenerator generator = KeyPairGenerator.getInstance("SHA256withRSA");
        generator.initialize(2048, new SecureRandom());
        KeyPair pair = generator.generateKeyPair();

        return pair;
    }
    
    
    public static String encriptar(String plainText, PublicKey publicKey) throws Exception {
        Cipher encryptCipher = Cipher.getInstance("SHA256withRSA");
        encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey);

        byte[] cipherText = encryptCipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));

        return Base64.getEncoder().encodeToString(cipherText);
    }
    
    public static String decriptar(String cipherText, PrivateKey privateKey) throws Exception {
        byte[] bytes = Base64.getDecoder().decode(cipherText);

        Cipher decriptCipher = Cipher.getInstance("SHA256withRSA");
        decriptCipher.init(Cipher.DECRYPT_MODE, privateKey);

        return new String(decriptCipher.doFinal(bytes), StandardCharsets.UTF_8);
    }
    
}

在使用“ SHA256withRSA ”實例化密鑰對生成器和密碼時,您嘗試生成可用於簽名但不能用於加密的 RSA 密鑰。

您需要將 KeyPairGenerator 更改為“RSA”,將 Cipher 更改為“RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING”[或 Java 上的其他可用密碼],才能讓您的代碼運行。

您可以在下面找到包含更正的部分代碼和一個加密 email 地址並稍后將密文解密為解密文本的小示例。

請注意,此示例代碼沒有異常處理,僅用於教育目的。

output:

How do I have my own public key to encrypt data
ciphertext: lVN6XLO7LxMASVifq2J1/T8Hv40AUeOml3+MjA6u+mKv1EcJHQO7gbZpMCrhO1fzo3s5tGRQl38iumMDqLBp+ApxQkPKeVVU99oOeuzYZb9fwyBH1/b4AEC1UDdFBWwH6rN/MuG17FyBrq/JR64upcM79gITdrIywvd32gYCd+XrGcGIxDoDGufQ1iqjjOihnRdYkYQDhUNEhi3clTz+ZDJ1EqMZmfc+v9Fsnsit2q9wbO3C33Hjbj/gY8AIMOpE7KYGupnpvR+WQk1DvmqiDoIDNfweRvwqF9m+7AUldAxxmjPN0C/WFmYPfZHUFSBK/0+8Ix5pDNw4l3C8thWKeg==
decryptedtext: myEmail@stackoverflow.com

代碼:

import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.util.Base64;

public class Main {
    public static void main(String[] args) throws Exception {
        System.out.println("How do I have my own public key to encrypt data");
        // string to encrypt
        String plaintext = "myEmail@stackoverflow.com";
        // keypair generation
        KeyPair keyPair = gerarParDeChaves();
        // encryption
        PublicKey publicKey = keyPair.getPublic();
        String ciphertext = encriptar(plaintext, publicKey);
        System.out.println("ciphertext: " + ciphertext);
        // decryption
        PrivateKey privateKey = keyPair.getPrivate();
        String decryptedtext = decriptar(ciphertext, privateKey);
        System.out.println("decryptedtext: " + decryptedtext);
    }
    public static KeyPair gerarParDeChaves() throws Exception {
        //KeyPairGenerator generator = KeyPairGenerator.getInstance("SHA256withRSA"); // used for signatures
        KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
        generator.initialize(2048, new SecureRandom());
        KeyPair pair = generator.generateKeyPair();
        return pair;
    }

    public static String encriptar(String plainText, PublicKey publicKey) throws Exception {
        //Cipher encryptCipher = Cipher.getInstance("SHA256withRSA"); // used for signatures
        Cipher encryptCipher = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING");
        encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] cipherText = encryptCipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(cipherText);
    }

    public static String decriptar(String cipherText, PrivateKey privateKey) throws Exception {
        byte[] bytes = Base64.getDecoder().decode(cipherText);
        //Cipher decriptCipher = Cipher.getInstance("SHA256withRSA"); // used for signatures
        Cipher decriptCipher = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING");
        decriptCipher.init(Cipher.DECRYPT_MODE, privateKey);
        return new String(decriptCipher.doFinal(bytes), StandardCharsets.UTF_8);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM