有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java El Gamal明文加密(非数字)不工作

下面是我加密明文(不是数字)的JAVA代码。 代码包括加密和解密

解密的文本与明文不匹配,我在做什么

如果我将BigInteger m = new BigInteger(msg.getBytes());替换为此代码BigInteger m = new BigInteger(msg);,则我的代码可以工作

package com.porsche.main;

import java.util.*;
import java.math.BigInteger;

public class ElGamal {

    // Get user input for prime.
    // static BigInteger p = new BigInteger("13256401");
    static BigInteger p = new BigInteger("14893003337626352152463254152616458181260144281");
    
    // Calculate a generator.
    // static BigInteger g = new BigInteger("957");
    static BigInteger g = new BigInteger("4893003337626352152463254152616458181260144281");

    // Pick a secret a.
    // BigInteger a = new BigInteger(p.bitCount()-1, r);
    static BigInteger a = new BigInteger("843900337326351225463254152616458181260144281");
    
    public static void main(String[] args) {
    
        Random r = new Random();    
        
        // Calculate the corresponding public b.
        BigInteger b = g.modPow(a, p);
    
        // Print out our public keys.
        System.out.println("p = " + p);
        System.out.println("g = " + g);
        System.out.println("b = " + b);
    
        // When we send a message, the sender picks a random k.
        BigInteger k = new BigInteger(p.bitCount()-1, r);
        
        // Here, the sender starts calculating parts of the cipher text that
        // don't involve the actual message.
        BigInteger c1 = g.modPow(k, p);
        BigInteger c2 = b.modPow(k, p);
    
        // Here we get the message from the user.
        String msg = "12345678901234567890123456789012345678901234567";
        BigInteger m = new BigInteger(msg.getBytes());
        System.out.println("The message encryption = " + msg);
    
        // Now, we can calculate the rest of the second cipher text.
        c2 = c2.multiply(m);
        c2 = c2.mod(p);
    
        // Print out the two cipher texts.
        System.out.println("The corresponding cipher texts are");
        System.out.println("c1 = " + c1);
        System.out.println("c2 = " + c2);
    
        // First, determine the inverse of c1 raised to the a power mod p.
        BigInteger temp = c1.modPow(a,p);
        temp = temporariness(p);

        // Print this out.
        System.out.println("Here is c1^ -a = "+temp);

        // Now, just multiply this by the second cipher text
        BigInteger recover = temp.multiply(c2);
        recover = recover.mod(p);
    
        // And this will give us our original message back!
        System.out.println("The decrypted message = "+recover);
    }
}

共 (1) 个答案

  1. # 1 楼答案

    您提供的关于“El Gamal”算法的信息非常少,因此很难找到代码没有按预期工作的原因。在网络中搜索一点,我发现了一个与您的非常相似的工作示例代码,它正在工作(http://faculty.washington.edu/moishe/javademos/Security/ElGamal.java

    请记住,使用BigInteger变量意味着您将得到非常大的数字,这限制了您可以使用的数据(“明文”)的大小。示例代码最多可以加密19个字符&;解密后,较长的明文将不起作用。因此,我使用了与您不同的明文(“9876543210987654321”)

    结果如下:

    El Gamal encryption of clear Text
    
    secretKey = 12345678901234567890
    p = 15228497165243954393
    b = 3
    c = 2082886678951242957
    Enter your Big Number message  > Plaintext = 9876543210987654321
    
    Encryption
    r = 8874033432052511920
    EC = 2442890351962647176
    b^r mod p = 8525328674077426405
    
    Decryption
    c^r mod p = 11673994647641103379
    d = 9011480367194984320
    Alice decodes: 9876543210987654321
    

    这是工作代码(与链接代码相比变化最小):

    import java.math.*;
    import java.util.*;
    import java.security.*;
    import java.io.*;
    
    public class ElGamal2
    {
        public static void main(String[] args) throws IOException
        {
            // source http://faculty.washington.edu/moishe/javademos/Security/ElGamal.java
            System.out.println("El Gamal encryption of clear Text\n");
            String msg = "9876543210987654321";
            BigInteger p, b, c, secretKey;
            Random sc = new SecureRandom();
            secretKey = new BigInteger("12345678901234567890");
            //
            // public key calculation
            //
            System.out.println("secretKey = " + secretKey);
            p = BigInteger.probablePrime(64, sc);
            b = new BigInteger("3");
            c = b.modPow(secretKey, p);
            System.out.println("p = " + p);
            System.out.println("b = " + b);
            System.out.println("c = " + c);
            //
            // Encryption
            //
            System.out.print("Enter your Big Number message  > ");
            //String s = Tools.getString();
            String s = msg;
            BigInteger X = new BigInteger(s);
            BigInteger r = new BigInteger(64, sc);
            BigInteger EC = X.multiply(c.modPow(r, p)).mod(p);
            BigInteger brmodp = b.modPow(r, p);
            System.out.println("Plaintext = " + X);
            System.out.println("\nEncryption");
            System.out.println("r = " + r);
            System.out.println("EC = " + EC);
            System.out.println("b^r mod p = " + brmodp);
            //
            // Decryption
            //
            System.out.println("\nDecryption");
            BigInteger crmodp = brmodp.modPow(secretKey, p);
            BigInteger d = crmodp.modInverse(p);
            BigInteger ad = d.multiply(EC).mod(p);
            System.out.println("c^r mod p = " + crmodp);
            System.out.println("d = " + d);
            System.out.println("Alice decodes: " + ad);
        }
    }
    

    编辑: 关于你的评论“谢谢你的回复。明文是否只需要是所有数字,它可以是类似“Hellow World!“?”:

    根据JavaDocs(https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/math/BigInteger.html),使用这些构造函数创建一个BigInteger,并且所有构造函数都有一个共同点——它必须是一个表示BigInteger值的数字,而不是一个字符:

    BigInteger​(byte[] val)
    Translates a byte array containing the two's-complement binary representation of a BigInteger into a BigInteger.
    
    BigInteger​(byte[] val, int off, int len)
    Translates a byte sub-array containing the two's-complement binary representation of a BigInteger into a BigInteger.
    
    BigInteger​(int signum, byte[] magnitude)
    Translates the sign-magnitude representation of a BigInteger into a BigInteger.
    
    BigInteger​(int signum, byte[] magnitude, int off, int len)
    Translates the sign-magnitude representation of a BigInteger into a BigInteger.
    
    BigInteger​(int bitLength, int certainty, Random rnd)
    Constructs a randomly generated positive BigInteger that is probably prime, with the specified bitLength.
    
    BigInteger​(int numBits, Random rnd)
    Constructs a randomly generated BigInteger, uniformly distributed over the range 0 to (2numBits - 1), inclusive.
    
    BigInteger​(String val)
    Translates the decimal String representation of a BigInteger into a BigInteger.
    
    BigInteger​(String val, int radix)
    Translates the String representation of a BigInteger in the specified radix into a BigInteger.