【问题标题】:How to Encrypt String With Public Key and Decrypt with Private key ?如何使用公钥加密字符串并使用私钥解密?
【发布时间】:2015-11-02 03:14:15
【问题描述】:

我想用来自服务器的密钥加密密码并在服务器端解密加密的密码。这是我在我的应用程序中使用的代码

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package publicprivatekey;

import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import javax.crypto.*;

/**
 *
 * @author Rajorshi
 */
public class PublicPrivateKey {

    public static String getEncrypted(String data, String Key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidKeySpecException, IllegalBlockSizeException, BadPaddingException {
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(Base64.getDecoder().decode(Key.getBytes())));
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] encryptedbytes = cipher.doFinal(data.getBytes());
        return new String(Base64.getEncoder().encode(encryptedbytes));
    }

    public static String getDecrypted(String data, String Key) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        PrivateKey pk = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(Key.getBytes())));
        cipher.init(Cipher.DECRYPT_MODE, pk);
        byte[] encryptedbytes = cipher.doFinal(Base64.getDecoder().decode(data.getBytes()));
        return new String(encryptedbytes);
    }

    public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        // TODO code application logic here
        KeyGenerator keyGenerator = KeyGenerator.getInstance("Blowfish");
        keyGenerator.init(448);
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(1024);
        KeyPair keyPair = keyPairGenerator.genKeyPair();

        String pubKey = new String(Base64.getEncoder().encode(keyPair.getPublic().getEncoded()));
        String priKey = new String(Base64.getEncoder().encode(keyPair.getPrivate().getEncoded()));
        System.out.println("Public Key:" + pubKey);
        System.out.println("Private Key:" + priKey);
        String cipherText = getEncrypted("hi this is a string", pubKey);

        System.out.println("CHIPHER:" + cipherText);
        String decryptedText = getDecrypted(cipherText, priKey);
        System.out.println("DECRYPTED STRING:" + decryptedText);

    }

}

我想用来自服务器的密钥加密密码并在服务器端解密加密的密码。这是我在我的应用程序中使用的代码。

【问题讨论】:

  • 欢迎来到 SO。请阅读:How to Ask
  • 到底是什么问题?
  • 你没有说明你的问题到底是什么,但你根本不应该加密密码。请参阅 password-encryption 标签 wiki 了解原因。
  • 你不应该在纯文本上做公钥和私钥,因为我们有对称密钥加密。非对称密钥加密用于秘密传输symmetric key
  • 我手头有一些examples。但是,如果您正在寻找传输中的加密(通过网络传递某些东西的安全方式),通常最好的答案是使用 https。

标签: java public-key-encryption password-encryption


【解决方案1】:

你可以用 Scala 或 Spark + scala 做:

object App {
  def main(args: Array[String]): Unit = {


    println("************hello*******************\n")


    val generator = KeyPairGenerator.getInstance("RSA")

    generator.initialize(2048)
    val pair = generator.generateKeyPair
    val privateKey = pair.getPrivate
    val publicKey = pair.getPublic
    //println("private key: ",privateKey)
    println("public Key: ", publicKey)

    //Convert the keys to string using encodeToString()
    val publicKeyString = getEncoder.encodeToString(publicKey.getEncoded());

    println("publicKeyString :", publicKeyString)

    val privateKeyString = getEncoder.encodeToString(privateKey.getEncoded());

    println("privateKeyString :", privateKeyString)

    val spark = SparkSession.builder()
      .master("local")
      .appName("rsa_test")
      .enableHiveSupport()
      .config("spark.sql.parquet.compression.codec", "snappy")
      .config("parquet.block.size", 268435456)
      .config("hive.exec.dynamic.partition.mode", "nonstrict")
      .getOrCreate()

    def RsaEncryption(inParm: String): Array[Byte] = {

      //Create a Cipher object.The Cipher will provide the functionality of a
      // cryptographic cipher for encryption and decryption.
      val encryptionCipher = Cipher.getInstance("RSA")
      //init() method initializes the cipher with a key for encryption, decryption, key wrapping,
      // or key unwrapping depending on the value of opmode
      encryptionCipher.init(Cipher.ENCRYPT_MODE, privateKey)
      //The doFinal() method performs the encryption operation depending on how the cipher was initialized
      // and resets once it finishes allowing encrypting more data.

      val encryptedMessage = encryptionCipher.doFinal(inParm.getBytes)

      return encryptedMessage
      //return encryption
    }

    def RsaDecryption(inParm: Array[Byte]): String = {
      val decryptionCipher = Cipher.getInstance("RSA")
      decryptionCipher.init(Cipher.DECRYPT_MODE, publicKey)
      val decryptedMessage = decryptionCipher.doFinal(inParm)
      val decryption = new String(decryptedMessage)
      return decryption
    }

    val secretMessage = "Test string for encryption"
    val encryptedMessage = RsaEncryption(secretMessage)
    println("encryptedMessage is :"+encryptedMessage)
    //The method returns an array of bites which is simply our message, and we can convert it to a string
    // and log it to the console to verify our text is similar to the decrypted text.

    System.out.println("Encrypted Message = " + getEncoder.encodeToString(RsaEncryption(secretMessage)))

    // register udf below
    val clearTxt = "It will be done through spark 2.12"
    spark.udf.register("rsa_encrypt", (clearTxt: String) => getEncoder.encodeToString(RsaEncryption(clearTxt)))
    val text = s"""select rsa_encrypt(\"$clearTxt\") as enc_string"""
    println(text)
    val df1 = spark.sql(text)
    val encString = df1.select(col("enc_string")).collectAsList().get(0)(0).toString().getBytes()
    //val encString1 = df1.withColumn("enc2",col("enc_string").cast(Array[Byte]()))

    println("Showing string : " + encString)
    println("Decoder call "+ getDecoder.decode(encString))
    val decodedString = getDecoder.decode(encString)

    def manOf[T: Manifest](t: T): Manifest[T] = manifest[T]

    println("Data type of df value " + manOf(getEncoder.encodeToString(RsaEncryption(secretMessage))))

    df1.show(truncate=false)
    //Decrypt message

    val decryptionCipher = Cipher.getInstance("RSA")
    decryptionCipher.init(Cipher.DECRYPT_MODE, publicKey)


    val decryptedMessage = decryptionCipher.doFinal(encryptedMessage)
    val decryption = new String(decryptedMessage)
    println("=>"+decryption)
    //System.out.println("decrypted message = " + RsaDecryption(encryptedMessage))

    System.out.println("decrypted message2 = " +RsaDecryption(decodedString))
  }
}

【讨论】:

    【解决方案2】:

    如果您正在寻找一个 java 程序来使用公钥加密数据并使用私钥解密,那么这里是代码(使用 RSA 算法),

    import java.security.KeyFactory;
    import java.security.KeyPair;
    import java.security.KeyPairGenerator;
    import java.security.NoSuchAlgorithmException;
    import java.security.NoSuchProviderException;
    import java.security.PrivateKey;
    import java.security.PublicKey;
    import java.security.SecureRandom;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    
    import javax.crypto.Cipher;
    
    /**
     * @author visruthcv
     *
     */
    public class CryptographyUtil {
    
        private static final String ALGORITHM = "RSA";
    
        public static byte[] encrypt(byte[] publicKey, byte[] inputData)
                throws Exception {
    
            PublicKey key = KeyFactory.getInstance(ALGORITHM)
                    .generatePublic(new X509EncodedKeySpec(publicKey));
    
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, key);
    
            byte[] encryptedBytes = cipher.doFinal(inputData);
    
            return encryptedBytes;
        }
    
        public static byte[] decrypt(byte[] privateKey, byte[] inputData)
                throws Exception {
    
            PrivateKey key = KeyFactory.getInstance(ALGORITHM)
                    .generatePrivate(new PKCS8EncodedKeySpec(privateKey));
    
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, key);
    
            byte[] decryptedBytes = cipher.doFinal(inputData);
    
            return decryptedBytes;
        }
    
        public static KeyPair generateKeyPair()
                throws NoSuchAlgorithmException, NoSuchProviderException {
    
            KeyPairGenerator keyGen = KeyPairGenerator.getInstance(ALGORITHM);
    
            SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
    
            // 512 is keysize
            keyGen.initialize(512, random);
    
            KeyPair generateKeyPair = keyGen.generateKeyPair();
            return generateKeyPair;
        }
    
        public static void main(String[] args) throws Exception {
    
            KeyPair generateKeyPair = generateKeyPair();
    
            byte[] publicKey = generateKeyPair.getPublic().getEncoded();
            byte[] privateKey = generateKeyPair.getPrivate().getEncoded();
    
            byte[] encryptedData = encrypt(publicKey,
                    "hi this is Visruth here".getBytes());
    
            byte[] decryptedData = decrypt(privateKey, encryptedData);
    
            System.out.println(new String(decryptedData));
    
        }
    
    }
    

    【讨论】:

    • 我认为 init 函数的值不正确。根据 Java API 文档,cipher.init() 方法的第一个参数应该是以下之一:ENCRYPT_MODE、DECRYPT_MODE、WRAP_MODE 或 UNWRAP_MODE。
    • @opeongo PUBLIC_KEYENCRYPT_MODE 的值为 1,PRIVATE_KEYDECRYPT_MODE 的值为 2,因此它可以按预期工作,但我使用最合适的常量名称对其进行了修改。感谢您通知此事。
    • 您能建议我如何生成公钥和私钥,例如............ -----BEGIN PGP PUBLIC KEY BLOCK----- mI0EXEMqFwEEANS1o8wI2kW1bIohbEyygDBkuP0hLo4EE98S2ZfMpM2Fs4m8sHkD =arHQ -----END PGP PUBLIC KEY BLOCK-----
    猜你喜欢
    • 2011-06-17
    • 2021-04-01
    • 2013-06-08
    • 2015-07-31
    • 2012-04-21
    • 2021-02-17
    • 1970-01-01
    • 2015-01-25
    • 2015-08-23
    相关资源
    最近更新 更多