简体   繁体   中英

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

I have a User class, an Entity, and it must write the user's name and email in encrypted form with an asymmetric key (RSA) of size 2048.

The information will be encrypted with the public key of the client and he will decrypt using his private key.

@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
    
}

In the user service I call the methods created for encryption and decryption.

@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;
    }
}

But, I must create an endpoint for sending this user's public key, to client, for encryption.

How can I have my public key, and use it for this encryption and decryption?

Below my class to encrypt:

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);
    }
    
}

You try to generate RSA keys that can be used for signature but not for enryption when instantiating the keypairgenerator and cipher with "SHA256withRSA".

You need to change the KeyPairGenerator to "RSA" and the Cipher to "RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING" [or other available ciphers on your Java] to get your piece of code to run.

Below you find parts of your code with the corrections and a small example that encrypts an email address and later decrypts the ciphertext to the decryptedtext.

Please note that this example code does have no exception handling and is for educational purpose only.

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

code:

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);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM