如何解决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);
}
}
解决方法
您提供的有关“ 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值的数字,而不是char:
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 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.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。