精华内容
下载资源
问答
  • rsa数字签名

    2017-09-19 19:07:39
    RSA数字签名,对明文进行数字化,签名和验证,C语言,可直接运行。有界面,在文本框输入需签名的明文,再通过按钮进行操作。
  • RSA数字签名

    2015-05-08 14:58:49
    基于公开密码体制的数字签名 RSA数字签名
  • RSA数字签名源程序

    热门讨论 2008-06-06 19:10:02
    RSA数字签名源程序RSA数字签名源程序RSA数字签名源程序RSA数字签名源程序RSA数字签名源程序RSA数字签名源程序RSA数字签名源程序RSA数字签名源程序
  • C++编写的rsa数字签名程序源代码
  • RSA数字签名 ** 一、实验目的 ** 学习RSA算法在数字签名方面的使用,掌握公钥签名中最基础的签名算法-RSA数字签名算法的编写。 二、实验要求 1. 熟悉RAS基本算法。 2. 熟悉RAS数字签名算法。 3. 掌握如何使用Java...

    RSA数字签名

    **

    一、实验目的

    **
    学习RSA算法在数字签名方面的使用,掌握公钥签名中最基础的签名算法-RSA数字签名算法的编写。

    二、实验要求

    1. 熟悉RAS基本算法。
    2. 熟悉RAS数字签名算法。
    3. 掌握如何使用JavaBigInteger类,简单实现最基础的RSA公私钥签名算法。

    三、开发环境

    JDK1.7,Java开发环境(本实验采用Windows+eclipse作为实验环境),要求参与实验的同学按照对称加密提供的方法,提前安装好JDK。
    四、实验内容
    【1-1】RAS签名算法的实现
    1.实现公私钥生成算法:根据书本上的知识, RAS公私钥生成算法首选需要选取两个大素数 和 ,并计算 ,进一步计算欧拉函数 。接着随机选取一个整数 满足 ,其中, 。最后,计算的 逆元 。因此,签名私钥为 ,公钥为 。具体的代码如下:
    public void initKeys() {
    BigInteger p = newBigInteger(1024, 500, new Random());
    BigInteger q = newBigInteger(1024, 500, new Random());
    assert(p.compareTo(q) != 0);
    n = p.multiply(q);
    BigIntegerfi_n = p.subtract(BigInteger.ONE)
    .multiply(q.subtract(BigInteger.ONE));
    e = newBigInteger(512, 100, new Random());
    d = e.modInverse(fi_n);
    System.out.println("n : " + n);
    System.out.println("e : " + e);
    System.out.println("d : " + d);
    }
    其中,需要在前面定义 、 和 三个全局变量。
    public class RSASignatureAlgorithm {
    BigIntegern;
    BigIntegere;
    BigIntegerd;

    2.实现签名算法:RSA签名算法是对待签名的消息 进行签名,具体签名的形式如下:

    此时, 即为签名后的信息。因此,可根据公式,写代码如下:
    public BigInteger signature(byte m[]) {
    BigInteger s = __hash(m).modPow(d, n);
    System.out.println("s : " + s);
    Return s;
    }
    而哈希函数的输出是一个值,其实现可以如下:
    public BigInteger __hash(byte m[]) {
    MessageDigest md;
    try {
    md = MessageDigest.getInstance(“SHA-256”);
    md.update(m);
    byte b[] = newbyte[33];
    System.arraycopy(md.digest(), 0, b, 1, 32);
    returnnewBigInteger(b);
    } catch (NoSuchAlgorithmException e) {
    System.out.println(“this cannot happen.”);
    }
    returnnull;
    }
    3.实现验证签名算法:RSA签名验证算法即判定公式 是否成立。因此,代码的实现可以如下来进行:
    public boolean verify(byte m[], BigInteger s) {
    BigIntegerleft = __hash(m).mod(n);
    BigInteger right = s.modPow(e, n);
    returnleft.compareTo(right) == 0;
    }
    4.实现main方法,在main方法中调用算法进行测试:
    publicstaticvoidmain(String args[]) {
    RSASignatureAlgorithmrs a = new RSASignatureAlgorithm();
    rsa.initKeys();
    byte m[] = “My name is XXX-, my students number is XXX.”.getBytes();
    BigInteger s = rsa.signature(m);
    System.out.println("Real signature verify result : " + rsa.verify(m, s));
    s = s.add(BigInteger.ONE);
    System.out.println("Faked signature verify result : " + rsa.verify(m, s));
    }
    【1-2】完整参考代码

    importjava.math.BigInteger;
    importjava.security.MessageDigest;
    importjava.security.NoSuchAlgorithmException;
    importjava.util.Random;
    
    
    public class RSASignatureAlgorithm {
    	BigInteger n;
    	BigInteger e;
    	BigInteger d;
    	
    	publicBigInteger __hash(byte m[]) {
    		MessageDigest md;
    		try {
    			md = MessageDigest.getInstance("SHA-256");
    			md.update(m);
    		byte b[] = newbyte[33];
    		System.arraycopy(md.digest(), 0, b, 1, 32);
    		return new BigInteger(b);
    		} catch (NoSuchAlgorithmException e) {
    			System.out.println("this cannot happen.");
    		}
    	return null;
    	}
    	
    	public void initKeys() {
    		BigInteger p = new BigInteger(1024, 500, new Random());
    		BigInteger q = new BigInteger(1024, 500, new Random());
    		assert(p.compareTo(q) != 0);
    		n = p.multiply(q);
    		BigIntegerfi_n = p.subtract(BigInteger.ONE)
    			.multiply(q.subtract(BigInteger.ONE));
    		e = newBigInteger(512, 100, new Random());
    		d = e.modInverse(fi_n);
    		
    		System.out.println("n : " + n);
    		System.out.println("e : " + e);
    		System.out.println("d : " + d);
    	}
    	
    	public BigInteger signature(byte m[]) {
    		BigInteger s = __hash(m).modPow(d, n);
    		System.out.println("s : " + s);
    		return s;
    	}
    	
    	public boolean verify(byte m[], BigInteger s) {
    		BigInteger left  = __hash(m).mod(n);
    		BigInteger right = s.modPow(e, n);
    		return left.compareTo(right) == 0;
    	}
    	
    	public static void main(String args[]) {
    		RSASignatureAlgorithm rsa = new RSASignatureAlgorithm();
    		rsa.initKeys();
    		byte m[] = "My name is XXX, my students number is XXX.".getBytes();
    		BigInteger s = rsa.signature(m);
    		System.out.println("Real  signature verify result : " + rsa.verify(m, s));
    		s = s.add(BigInteger.ONE);
    		System.out.println("Faked signature verify result : " + rsa.verify(m, s));
    	}
    }
    
    


    RSA签名算法是用其生成的私钥 来对待签名的消息 进行数据签名,而用其公钥 来进行验证。其中私钥 是进行秘密保存的,而且只有签名方才拥有该私钥,这就达到了不可否认性。如果两者用反了,就是RSA的加解密算法,也就是用公钥 来对消息 进行加密,而用私钥 来解密。此外,在教科书式学习中可以将随机数的大小从1024调到512,即可提高运行速度。

    展开全文
  • RSA算法和RSA数字签名算法的实现

    热门讨论 2011-05-29 14:01:52
    RSA算法和RSA数字签名算法的实现,RSA算法和RSA数字签名算法的实现,RSA算法和RSA数字签名算法的实现
  • 本代码主要用于实现RSA数字签名算法,用java进行编程,能够完整的在eclipse上运行,具体可用于密码学的课程设计等。
  • RSA 数字签名 c

    2010-05-25 22:44:15
    RSA 数字签名 c语言实现~可运行成功
  • C++编写的CRC32校验程序源代码 ; C++编写的DES加密程序源代码 ; C++编写的MD5算法程序源代码 ;...C++编写的rsa数字签名程序源代码 ; C++编写的RSA演示程序源代码 ; C++编写的简单移位程序源代码
  • 2.go语言实现RSA数字签名 2.1 数字签名【签名-核验】流程 2.1.1 使用rsa包生成密钥对 2.1.2 使用私钥对信息进行数字签名 2.1.3 使用公钥对数字签名进行校验 2.2 数字签名【签名-核验】模板 1.数字签名 ...

    目录

    1.数字签名

    1.1 概念

    1.2 原理

    1.3 实现

    2.go语言实现RSA数字签名

    2.1 数字签名【签名-核验】流程

    2.1.1 使用rsa包生成密钥对

    2.1.2 使用私钥对信息进行数字签名

    2.1.3 使用公钥对数字签名进行校验

    2.2 数字签名【签名-核验】模板


    1.数字签名

    1.1 概念

    数字签名,就是只有信息的发送者才能产生的别人无法伪造的一段数字串,这段数字串同时也是对信息的发送者发送信息真实性的一个有效证明。--摘自百度百科。其实本质上是为了解决消息验证的无法引入第三方公正缺陷问题而创造的一种方式,它用到的技术非常简单:

    信息发送者利用非对称加密私钥来对数据哈希值进行加密,然后将公钥公布,这样一来所有获得公钥的人都能够证明信息发送者真的发送了这条数据。这样不论是信息发送者对原始数据作出了修改,还是不承认这条数据发送,持有公钥的人们都能够轻而易举的识别出信息发送者的毁约操作;而同时不论信息遭到怎样的窃取篡夺,因为持有公钥的人们总是能够轻而易举识别出篡改后的信息哈希值与原信息的哈希值不同,进而保护了信息发送者信息数据的安全。可以说数字签名的出现直接解决了消息验证当中无法引入第三方公正的缺陷问题。

    1.2 原理

    由于数据发送方使用的是私钥加密,所以所有持有对应公钥的人都能够对这个数据进行解密进而进行签名校验。但是由于使用公钥解密出来的数据仍然是加密数据,必须使用对应的特殊key来解密才能真正得到明文内容,而这个特殊key是只有Frank和Alex拥有的。所以其他人尽管能够下载到Frank的公钥进行签名签证的第三方证明人,能够看到签名中的原始数据密文,但是仍旧无法真正看到密文背后真正的内容。

    此时,既然每个人都能持有公钥,那么就意味着Frank私自对原始数据作出任何修改都会导致数字签名变更。此时每一位持有公钥的用户对数字签名进行再次验证就会失败,所以Amy此时充当了Alex的证明人。从另一方面来说如果Alex毁约不承认Frank曾经对其发送过数据或者数据曾经被篡改,那么Amy此时依然可以充当Frank的证明人,因为Frank的确发送了数据,所以Amy的再次验证是能够成功的。这就是数字签名第三方公正的原理。

    1.3 实现

    经过刚才的原理分析,我们能够显然发现go语言中如果想要实现数字签名就必须实现非对称加密的密钥对的分发功能。非对称加密方式常见有两种:一种就是大名鼎鼎的RSA算法(我之前的文章中提到过),而另一种则是椭圆曲线(虽然很少听到但非常犀利,第二代人民币就是用这种方式加密的)。比较让人头大的地方在于:

    1. go语言只提供了RSA算法的非对称加密接口,而没有提供椭圆曲线的非对称加密接口!
    2. 然而go语言却同时提供了RSA算法的数字签名接口,和椭圆曲线的数字签名接口。

    这就意味着我们尽管在进行非对称加密操作的时候不能使用go语言一睹椭圆曲线的风采,但是可以直接调用现成的接口来进行椭圆曲线的数字签名功能。这不得不说是一次来自大佬的深深的鄙视(估计是怕公开给我们我们也不会...),所以本篇只讨论RSA数字签名。

    2.go语言实现RSA数字签名

    2.1 数字签名【签名-核验】流程

    2.1.1 使用rsa包生成密钥对

    1. 使用rsa包内的GenerateKey函数来生成密钥对,其中公钥数据保存在私钥数据中
    2. 使用x509包内的Marshal方法,将密钥信息序列化为ASN.1标准的DER编码字串(公钥私钥的Marshal方法不同)
    3. 使用pem包内的数据模型构建pem.Block数据块
    4. 使用pem包内的Encode方法将pem.Block数据块写入本地文件

    2.1.2 使用私钥对信息进行数字签名

    1. 使用os.Open打开私钥文件后,使用Read读取文件内容存入缓冲区
    2. 使用pem包中的Decode方法解码,将缓冲区中的文件流转换成一个存有ASN.1标准的DER编码字符串信息的pem.Block块
    3. 使用x509包中的Parse方法,将pem.Block包中的block.Bytes字段中的ASN.1标准的DER编码字符串解析,得到私钥
    4. 使用指定的hash单向散列函数计算出明文数据的散列值(创建哈希对象sha256.new()、然后write和sum那个玩意儿)
    5. 使用RSA包中提供的SignPKCS1v15方法,对私钥明文数据的散列值完成签名
    // SignPKCS1v15 calculates the signature of hashed using
    // RSASSA-PKCS1-V1_5-SIGN from RSA PKCS#1 v1.5.  Note that hashed must
    // be the result of hashing the input message using the given hash
    // function. If hash is zero, hashed is signed directly. This isn't
    // advisable except for interoperability.
    //
    // If rand is not nil then RSA blinding will be used to avoid timing
    // side-channel attacks.
    //
    // This function is deterministic. Thus, if the set of possible
    // messages is small, an attacker may be able to build a map from
    // messages to signatures and identify the signed messages. As ever,
    // signatures provide authenticity, not confidentiality.
    //
    //
    //参数1:rand.Reader加密随机数计数器
    //参数2:从私钥文件中读取到的私钥
    //参数3:选定生成散列值的hash算法。(语法要求:crypto.md5或者crypto.sha1或者crypto.sha256等)
    //参数4:明文数据根据选定hash算法生成的散列值
    //返回值:数字签名内容
    
    func SignPKCS1v15(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []byte) ([]byte, error) {
    	hashLen, prefix, err := pkcs1v15HashInfo(hash, len(hashed))
    	if err != nil {
    		return nil, err
    	}
    
    	tLen := len(prefix) + hashLen
    	k := priv.Size()
    	if k < tLen+11 {
    		return nil, ErrMessageTooLong
    	}
    
    	// EM = 0x00 || 0x01 || PS || 0x00 || T
    	em := make([]byte, k)
    	em[1] = 1
    	for i := 2; i < k-tLen-1; i++ {
    		em[i] = 0xff
    	}
    	copy(em[k-tLen:k-hashLen], prefix)
    	copy(em[k-hashLen:k], hashed)
    
    	m := new(big.Int).SetBytes(em)
    	c, err := decryptAndCheck(rand, priv, m)
    	if err != nil {
    		return nil, err
    	}
    
    	copyWithLeftPad(em, c.Bytes())
    	return em, nil
    }

    2.1.3 使用公钥对数字签名进行校验

    1. 使用os.Open打开下载的公钥文件后,使用Read读取文件内容存入缓冲区
    2. 使用pem包中的Decode方法解码,将缓冲区中的文件流转换成一个存有ASN.1标准的DER编码字符串信息的pem.Block块
    3. 使用x509包中的Parse方法,将pem.Block包中的block.Bytes字段中的ASN.1标准的DER编码字符串解析,得到公钥(记得断言)
    4. 使用与签名时一样的hash单向散列函数计算出接收到的明文数据的散列值
    5. 使用RSA包中提供的VerifyPKCS1v15方法,将下载的公钥接收到的明文数据的重新计算的散列值一并生成新的本地数字签名,然后与接收到的数字签名校验,得到结果
    // VerifyPKCS1v15 verifies an RSA PKCS#1 v1.5 signature.
    // hashed is the result of hashing the input message using the given hash
    // function and sig is the signature. A valid signature is indicated by
    // returning a nil error. If hash is zero then hashed is used directly. This
    // isn't advisable except for interoperability.
    //
    //
    //参数1:从公钥文件中读取到的公钥
    //参数2:选定生成散列值的hash算法。(语法要求:crypto.md5或者crypto.sha1或者crypto.sha256等)
    //参数3:根据接收的明文生成的本地散列值
    //参数4:接收到发送者发来数字签名
    //返回值:数字签名的校验结果
    //      返回nil代表校验成功
    //      返回不是nil代表校验失败
    
    func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte) error {
    	hashLen, prefix, err := pkcs1v15HashInfo(hash, len(hashed))
    	if err != nil {
    		return err
    	}
    
    	tLen := len(prefix) + hashLen
    	k := pub.Size()
    	if k < tLen+11 {
    		return ErrVerification
    	}
    
    	c := new(big.Int).SetBytes(sig)
    	m := encrypt(new(big.Int), pub, c)
    	em := leftPad(m.Bytes(), k)
    	// EM = 0x00 || 0x01 || PS || 0x00 || T
    
    	ok := subtle.ConstantTimeByteEq(em[0], 0)
    	ok &= subtle.ConstantTimeByteEq(em[1], 1)
    	ok &= subtle.ConstantTimeCompare(em[k-hashLen:k], hashed)
    	ok &= subtle.ConstantTimeCompare(em[k-tLen:k-hashLen], prefix)
    	ok &= subtle.ConstantTimeByteEq(em[k-tLen-1], 0)
    
    	for i := 2; i < k-tLen-1; i++ {
    		ok &= subtle.ConstantTimeByteEq(em[i], 0xff)
    	}
    
    	if ok != 1 {
    		return ErrVerification
    	}
    
    	return nil
    }

    2.2 数字签名【签名-核验】模板

    //创建函数生成RSA密钥对,而后本地化存储
    func GenerateRSAkeyForSign(keySize int){
        //私钥
        privateKey,err := rsa.GenerateKey(rand.Reader, keySize)
        if err!=nil{
        	panic(err)
        }
        derPrivateCode := x509.MarshalPKCS1PrivateKey(privateKey)
        peoPrivateBlock := pem.Block{Type:"FRANK RSA PRIVATE KEY",Bytes:derPrivateCode}
        filePrivate,err := os.Create("frankPrivate.pem")
        err = pem.Encode(filePrivate,&peoPrivateBlock)
        if err!=nil{
        	panic(err)
        }
        filePrivate.Close()
        //公钥
        publickKey := privateKey.PublicKey
        derPublicCode,pubErr := x509.MarshalPKIXPublicKey(&publickKey)
        if pubErr!=nil{
        	panic(pubErr)
        }
        peoPublicBlock := pem.Block{Type:"FRANK RSA PUBLIC KEY",Bytes:derPublicCode}
        filePublic,err := os.Create("frankPublic.pem")
        err = pem.Encode(filePublic,&peoPublicBlock)
        if err!=nil{
        	panic(err)
        }
        filePublic.Close()
    }
    //使用RSA私钥签名函数
    func RSAUsePrivateKeySign(plainText []byte, privateKeyFileName string) []byte{
        //1.将文件当中的加密私钥读出存入缓冲区
        privateFile,err := os.Open(privateKeyFileName)
        if err!=nil{
        	panic(err)
        }
        defer privateFile.Close()
        fileInfo,err := privateFile.Stat()
        if err!=nil{
        	panic(err)
        }
        buffer := make([]byte, fileInfo.Size())
        privateFile.Read(buffer)
        //2.pem解码,将数据流转换成一个存有DER字符串的pem.Block块
        block,_ := pem.Decode(buffer)
        //3.使用x509方法,对DER字符串解析,获取到私钥
        privateKey,err := x509.ParsePKCS1PrivateKey(block.Bytes)
        if err!=nil{
        	panic(err)
        }
        //4.生成明文消息对应的散列值
        hash256 := sha256.New()
        hash256.Write(plainText)
        hashValue := hash256.Sum(nil)
        //5.使用[私钥]和[散列值]完成签名(RSA包内的方法)
        codeSign,err := rsa.SignPKCS1v15(rand.Reader,privateKey,crypto.SHA256,hashValue)
        if err!=nil{
        	panic(err)
        }
        return codeSign
    }
    //使用RSA公钥校验函数
    func RSAUsePublicKeyVerify(plainText,codeSign []byte, publicKeyFileName string)(flag string){
        //1.将文件当中的加密公钥读出存入缓冲区
        publicFile,err := os.Open(publicKeyFileName)
        if err!=nil{
        	panic(err)
        }
        defer publicFile.Close()
        fileInfo,err := publicFile.Stat()
        if err!=nil{
        	panic(err)
        }
        buffer := make([]byte, fileInfo.Size())
        publicFile.Read(buffer)
        //2.pem解码,将数据流转换成一个存有DER字符串的pem.Block块
        block,_ := pem.Decode(buffer)
        //3.使用x509方法,对DER字符串解析,获取到公钥(记得断言)
        publicInterface,err := x509.ParsePKIXPublicKey(block.Bytes)
        if err!=nil{
        	panic(err)
        }
        publicKey := publicInterface.(*rsa.PublicKey)
        //4.生成明文消息对应的散列值
        hash256 := sha256.New()
        hash256.Write(plainText)
        hashValue := hash256.Sum(nil)
        //5.使用[公钥]和[散列值]完成签名校验(RSA包内的方法)
        err = rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, hashValue, codeSign)
        if err!=nil{
        	flag = "验证失败"
        }else{
        	flag = "验证成功"
        }
        return
    }
    func main(){
        plainText := []byte("helloworld今天天气好晴朗处处好风光")
        //数字签名
        codeSign := RSAUsePrivateKeySign(plainText, "frankPrivate.pem")
        //只是为了能看到所有内容而已,所以base64编码一下输出,不然都是乱码
        //实际核验操作还是是用codeSign
        result := hex.EncodeToString(codeSign);
        fmt.Printf("%s\n", result);
        //签名验证
        flag := RSAUsePublicKeyVerify(plainText, codeSign, "frankPublic.pem")
        fmt.Printf("%s\n",flag)
    }

    结果很轻松看到base64序列化之后的数字签名,长度刚好是我们选择的SHA256算法的hash哈希值长度。

     

    展开全文
  • 加密 RSA 数字签名 数字证书。顾名思义 我这个项目里面 有6个加密方法。自己看着下,绝对金典。分高的是有理由的。
  • 内容详细 资源详尽 完整的介绍了有关rsa数字签名的过程原理 有一定的借鉴作用~
  • RSA数字签名java实现

    2014-05-12 17:32:48
    根据上面的过程,我们可以得到RSA数字签名的框图如图2-1: 图 2-1 RSA数字签名框图 2、 假设Alice想和Bob通信,以本地两个文件夹Alice和Bob模拟两个用户,实现消息M和签名的模拟分发 (1)、Alice通过RSA算法生成...
  • Qt利用OpenSSl实现RSA数字签名 http://blog.csdn.net/usister/article/details/74390949资源描述 欢迎评论
  • Go语言实现RSA数字签名

    千次阅读 2018-11-06 11:50:43
    Go语言实现RSA数字签名 RSA是一种非对称加密算法,它的名字是由它的三位开发者,即RonRivest、AdiShamir和LeonardAdleman 的姓氏的首字母组成的(Rivest-Shamir-Adleman ),可用于数据加密和数字签名。 在用于数字...

    Go语言实现RSA数字签名


    RSA是一种非对称加密算法,它的名字是由它的三位开发者,即RonRivest、AdiShamir和LeonardAdleman 的姓氏的首字母组成的(Rivest-Shamir-Adleman ),可用于数据加密和数字签名。

    在用于数字签名时,发送方通常先对消息生成散列值,再利用私钥对散列值进行签名,接收方收到消息及签名时,也先对消息生成散列值(与发送方使用同种单向散列函数),利用发送方发的公钥、签名以及自己生成的散列值进行签名验证。

    实现代码如下:

    import (
    	"os"
    	"encoding/pem"
    	"crypto/x509"
    	"crypto/rsa"
    	"crypto/sha256"
    	"crypto/rand"
    	"crypto"
    	"fmt"
    )
    
    //生成RSA私钥和公钥,保存到文件中
    func GenerateRSAKey(bits int){
    	//GenerateKey函数使用随机数据生成器random生成一对具有指定字位数的RSA密钥
    	//Reader是一个全局、共享的密码用强随机数生成器
    	privateKey, err := rsa.GenerateKey(rand.Reader, bits)
    	if err!=nil{
    		panic(err)
    	}
    	//保存私钥
    	//通过x509标准将得到的ras私钥序列化为ASN.1 的 DER编码字符串
    	X509PrivateKey := x509.MarshalPKCS1PrivateKey(privateKey)
    	//使用pem格式对x509输出的内容进行编码
    	//创建文件保存私钥
    	privateFile, err := os.Create("private.pem")
    	if err!=nil{
    		panic(err)
    	}
    	defer privateFile.Close()
    	//构建一个pem.Block结构体对象
    	privateBlock:= pem.Block{Type: "RSA Private Key",Bytes:X509PrivateKey}
    	//将数据保存到文件
    	pem.Encode(privateFile,&privateBlock)
    
    	//保存公钥
    	//获取公钥的数据
    	publicKey:=privateKey.PublicKey
    	//X509对公钥编码
    	X509PublicKey,err:=x509.MarshalPKIXPublicKey(&publicKey)
    	if err!=nil{
    		panic(err)
    	}
    	//pem格式编码
    	//创建用于保存公钥的文件
    	publicFile, err := os.Create("public.pem")
    	if err!=nil{
    		panic(err)
    	}
    	defer publicFile.Close()
    	//创建一个pem.Block结构体对象
    	publicBlock:= pem.Block{Type: "RSA Public Key",Bytes:X509PublicKey}
    	//保存到文件
    	pem.Encode(publicFile,&publicBlock)
    }
    //读取RSA私钥
    func GetRSAPrivateKey(path string)*rsa.PrivateKey{
    	//读取文件内容
    	file, err := os.Open(path)
    	if err!=nil{
    		panic(err)
    	}
    	defer file.Close()
    	info, _ := file.Stat()
    	buf:=make([]byte,info.Size())
    	file.Read(buf)
    	//pem解码
    	block, _ := pem.Decode(buf)
    	//X509解码
    	privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
    	return privateKey
    }
    //读取RSA公钥
    func GetRSAPublicKey(path string)*rsa.PublicKey{
    	//读取公钥内容
    	file, err := os.Open(path)
    	if err!=nil{
    		panic(err)
    	}
    	defer file.Close()
    	info, _ := file.Stat()
    	buf:=make([]byte,info.Size())
    	file.Read(buf)
    	//pem解码
    	block, _ := pem.Decode(buf)
    	//x509解码
    	publicKeyInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
    	if err!=nil{
    		panic(err)
    	}
    	publicKey := publicKeyInterface.(*rsa.PublicKey)
    	return publicKey
    }
    //对消息的散列值进行数字签名
    func GetSign(msg []byte,path string)[]byte{
    	//取得私钥
    	privateKey:=GetRSAPrivateKey(path)
    	//计算散列值
    	hash := sha256.New()
    	hash.Write(msg)
    	bytes := hash.Sum(nil)
    	//SignPKCS1v15使用RSA PKCS#1 v1.5规定的RSASSA-PKCS1-V1_5-SIGN签名方案计算签名
    	sign, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, bytes)
    	if err!=nil{
    		panic(sign)
    	}
    	return sign
    }
    //验证数字签名
    func VerifySign(msg []byte,sign []byte,path string)bool{
    	//取得公钥
    	publicKey:=GetRSAPublicKey(path)
    	//计算消息散列值
    	hash := sha256.New()
    	hash.Write(msg)
    	bytes := hash.Sum(nil)
    	//验证数字签名
    	err:=rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, bytes, sign)
    	return err==nil
    }
    
    //测试RSA数字签名
    func main(){
    	//生成密钥文件
    	GenerateRSAKey1(2048)
    
    	//模拟发送方
    	//要发送的消息
    	msg:=[]byte("hello world")
    	//生成签名
    	sign:=GetSign(msg,"private.pem")
    
    	//模拟接收方
    	//接受到的消息
    	acceptmsg:=[]byte("hello world")
    	//接受到的签名
    	acceptsign:=sign
    	//验证签名
    	result:=VerifySign(acceptmsg,acceptsign,"public.pem")
    	fmt.Println("验证结果:",result)
    }
    

    测试结果如下:
    RSA数字签名测试结果

    展开全文
  • RSA数字签名源代码

    热门讨论 2010-01-29 22:13:18
    C# RSA数字签名源代码,一般,我们可以用RSA算法生成一对密钥,公钥发放给外部客户,私钥自己保管;有以下一些应用场景: 【公钥加密、私钥解密】或者【私钥加密、公钥验证】
  • RSA数字签名算法的模拟实现 摘 要 本程序为简易版RSA算法加密解密过程的模拟实现 程序分为加密和验证两部分根据课上所学的MD5加密过程以及RSA算法本程序采用MD5算法先对文件内容进行加密得到文字摘要再利用RSA算法...
  • RSA数字签名系统c源码

    热门讨论 2009-12-21 21:17:54
    用devc++编译器,c语言编写的RSA数字签名系统,代码简单易懂。
  • RSA 数字签名—— Java 实现

    千次阅读 2019-05-10 18:28:25
    RSA 数字签名—— Java 实现依赖代码运行结果 依赖 <dependency> <groupId>commons-net</groupId> <artifactId>commons-net</artifactId> <version>3...

    RSA 数字签名—— Java 实现

    依赖

           <dependency>
                <groupId>commons-net</groupId>
                <artifactId>commons-net</artifactId>
                <version>3.6</version>
            </dependency>
            <dependency>
                <groupId>commons-codec</groupId>
                <artifactId>commons-codec</artifactId>
                <version>1.9</version>
            </dependency>
    
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>1.7.25</version>
            </dependency>
    

    代码

    package awesome.data.structure.algorithm.encrypt.rsa;
    
    import awesome.data.structure.algorithm.encrypt.md5.Md5Util;
    import org.apache.tomcat.util.codec.binary.Base64;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import java.security.*;
    import java.security.spec.InvalidKeySpecException;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.TreeMap;
    
    /**
     * RSA 工具类
     *
     * @author: Andy
     * @time: 2019/5/10 16:50
     * @since
     */
    public class RSAUtil {
        private static final Logger LOGGER = LoggerFactory.getLogger(RSAUtil.class);
    
        private static final int RSA_SIZE_1024 = 1024;
    
        private static final String ALGORITHM = "SHA1WithRSA";
    
        /**
         * 生成 RSA 密钥对
         *
         * @param keySize
         * @return: {@link Map<String,Object> }
         * @author: Andy
         * @time: 2019/5/10 16:59
         */
        public static Map<String, Object> createKeyPair(int keySize) {
            KeyPairGenerator keyGen = null;
            try {
                keyGen = KeyPairGenerator.getInstance("RSA");
            } catch (NoSuchAlgorithmException e) {
                LOGGER.error("初始化密钥工具异常", e);
                return null;
            }
            keyGen.initialize(keySize, new SecureRandom());
            KeyPair key = keyGen.generateKeyPair();
            PublicKey publicKey = key.getPublic();
            PrivateKey privateKey = key.getPrivate();
            Map map = new HashMap();
            map.put("publicKey", publicKey);
            map.put("privateKey", privateKey);
            map.put("publicKeyBase64", Base64.encodeBase64String(publicKey.getEncoded()));
            map.put("privateKeyBase64", Base64.encodeBase64String(privateKey.getEncoded()));
            return map;
        }
    
        /**
         * 获得公钥的 Base64 字符串
         *
         * @param publicKey 公钥
         * @return: {@link String }
         * @author: Andy
         * @time: 2019/5/10 17:11
         */
        public static String getBase64PublicKeyString(PublicKey publicKey) {
            return Base64.encodeBase64URLSafeString(publicKey.getEncoded()).trim();
        }
    
        /**
         * 获得私钥的 Base64 字符串
         *
         * @param privateKey 公钥
         * @return: {@link String }
         * @author: Andy
         * @time: 2019/5/10 17:11
         */
        public static String getBase64PrivateKeyString(PrivateKey privateKey) {
            return Base64.encodeBase64URLSafeString(privateKey.getEncoded()).trim();
        }
    
        /**
         * 获取公钥
         *
         *
         * @param publicKeyBase64 公钥的 Base64 字符串
         * @return: {@link PublicKey }
         * @author: Andy
         * @time: 2019/5/10 18:05
         */
        public static PublicKey getPublicKey(String publicKeyBase64)
                throws NoSuchAlgorithmException, InvalidKeySpecException {
            X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(org.apache.commons.net.util.Base64.decodeBase64(publicKeyBase64));
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PublicKey publicKey = keyFactory.generatePublic(pubKeySpec);
            return publicKey;
        }
    
        /**
         * 获取私钥
         *
         *
         * @param privateKeyBase64 私钥的 Base64 字符串
         * @return: {@link PrivateKey }
         * @author: Andy
         * @time: 2019/5/10 18:05
         */
        public static PrivateKey getPrivateKey(String privateKeyBase64)
                throws NoSuchAlgorithmException, InvalidKeySpecException {
            PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(org.apache.commons.net.util.Base64.decodeBase64(privateKeyBase64));
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PrivateKey priKey = keyFactory.generatePrivate(priKeySpec);
            return priKey;
        }
    
    
        /**
         * 使用私钥对数据进行数字签名
         *
         * @param data       需要签名的数据
         * @param privateKey 私钥
         * @return: {@link byte[] }
         * @author: Andy
         * @time: 2019/5/10 17:15
         */
        public static byte[] sign(byte[] data, PrivateKey privateKey)
                throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
            Signature signature = Signature.getInstance(ALGORITHM);
            signature.initSign(privateKey);
            signature.update(data);
            return signature.sign();
        }
    
        /**
         * 使用私钥对数据进行数字签名
         *
         * @param data       需要签名的字符串
         * @param privateKey 私钥
         * @return: {@link String }
         * @author: Andy
         * @time: 2019/5/10 17:15
         */
        public static String sign(String data, PrivateKey privateKey)
                throws InvalidKeyException, NoSuchAlgorithmException, SignatureException {
            return Base64.encodeBase64URLSafeString(sign(data.getBytes(), privateKey)).trim();
        }
    
        /**
         * 签名校验
         *
         * @param data      参与签名的数据
         * @param sign      数字签名
         * @param publicKey 公钥
         * @return: {@link boolean }
         * @author: Andy
         * @time: 2019/5/10 17:22
         */
        public static boolean verify(byte[] data, byte[] sign, PublicKey publicKey)
                throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
            Signature signature = Signature.getInstance(ALGORITHM);
            signature.initVerify(publicKey);
            signature.update(data);
            return signature.verify(sign);
        }
    
        /**
         * 签名校验
         *
         * @param data      参与签名的数据
         * @param sign      数字签名
         * @param publicKey 公钥
         * @return: {@link boolean }
         * @author: Andy
         * @time: 2019/5/10 17:22
         */
        public static boolean verify(String data, String sign, PublicKey publicKey)
                throws InvalidKeyException, NoSuchAlgorithmException, SignatureException {
            return verify(data.getBytes(), Base64.decodeBase64(sign), publicKey);
        }
    
        /**
         * 获取参与签名的参数的字符串。参数拼接的顺序由 TreeMap 决定。
         *
         * @param paramsMap 参与签名的参数名和参数值的映射
         * @return: {@link String }
         * @author: Andy
         * @time: 2019/5/10 17:43
         */
        public static String getSourceSignData(TreeMap<String, String> paramsMap) {
            StringBuilder paramsBuilder = new StringBuilder();
            boolean first = true;
            for (Map.Entry<String, String> paramEntry : paramsMap.entrySet()) {
                if(!first){
                    paramsBuilder.append("&");
                }else {
                    first = false;
                }
    
                paramsBuilder.append(paramEntry.getKey()).append("=").append(paramEntry.getValue());
            }
    
            return paramsBuilder.toString();
        }
    
    
        /**
         * 设计流程:
         * <p>
         * 1、创建密钥对
         * 2、获取参与签名的数据
         * 3、获取参与签名的数据的摘要(MD5值)
         * 4、使用私钥对摘要进行数字签名
         * 5、使用公钥验证签名
         *
         * @author: Andy
         * @time: 2019/5/10 17:32
         */
        public static void main(String[] args) throws InvalidKeySpecException, NoSuchAlgorithmException, SignatureException, InvalidKeyException {
            //1、创建密钥对
            Map<String, Object> keyPairMap = createKeyPair(RSA_SIZE_1024);
            String publicKeyBase64 = keyPairMap.get("publicKeyBase64").toString();
            String privateKeyBase64 = keyPairMap.get("privateKeyBase64").toString();
            System.out.println(String.format("publicKeyBase64: %s", publicKeyBase64));
            System.out.println(String.format("privateKeyBase64: %s", privateKeyBase64));
    
            //2、获取参与签名的数据
            //创建 TreeMap, 排序方式为字符串的自然顺序
            TreeMap<String, String> paramsMap = new TreeMap<>();
            paramsMap.put("token", "token");
            paramsMap.put("batchNo", "批次号");
            paramsMap.put("totalBillCount", "1");
            paramsMap.put("sumMoney", "1");
            paramsMap.put("idCard", "452626199212070014");
            paramsMap.put("name", "张三");
            paramsMap.put("afterTaxMoney", "1");
            paramsMap.put("remark", "备注");
            String sourceSignData = getSourceSignData(paramsMap);
            System.out.println(String.format("参与签名的数据: %s", sourceSignData));
    
            //3、获取参与签名的数据的摘要(MD5值)
            String md5Str = Md5Util.encrypt(sourceSignData);
            System.out.println(String.format("参与签名的数据的摘要(MD5值): %s", md5Str));
    
            //4、使用私钥对摘要进行数字签名
            String signature = sign(md5Str, getPrivateKey(privateKeyBase64));
            System.out.println(String.format("数字签名: %s", signature));
    
            //5、使用公钥验证签名
            boolean success = verify(md5Str, signature, getPublicKey(publicKeyBase64));
    
            System.out.println(String.format("签名验证结果:%s", success));
    
        }
    
    
    
    }
    
    package awesome.data.structure.algorithm.encrypt.md5;
    
    
    import org.apache.commons.codec.digest.DigestUtils;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    /**
     * Md5 工具类
     *
     * @author: Andy
     * @time: 2019/5/10 17:27
     * @since
     */
    public class Md5Util {
        private static final Logger LOGGER = LoggerFactory.getLogger(Md5Util.class);
    
        /**
         * 简单 MD5 加密
         *
         * @param str
         * @return: {@link String }
         * @author: Andy
         * @time: 2019/4/29 15:28
         * @since
         */
        public static String encrypt(String str) {
            try {
                return DigestUtils.md5Hex(str).toUpperCase();
            } catch (Exception e) {
                LOGGER.error("MD5加密失败!", e);
            }
            return null;
        }
    }
    
    
    

    运行结果

    publicKeyBase64: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCMcizy+1sAprsTLKyk8DLU8yR29ZMuol7T50LeyG4JMQxewXm05g56UlVg1cx8FAJCrMUg6ZU8KyjJycP+au9mkGsRUZv2k5Pwahhmt9Y2yviuIDUuGJ3/4ojgvaqsxSE+yQi+rLconS5DxwOOTJ0Dp5nG7eo5auVCkk8+uy7JlwIDAQAB
    privateKeyBase64: MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAIxyLPL7WwCmuxMsrKTwMtTzJHb1ky6iXtPnQt7IbgkxDF7BebTmDnpSVWDVzHwUAkKsxSDplTwrKMnJw/5q72aQaxFRm/aTk/BqGGa31jbK+K4gNS4Ynf/iiOC9qqzFIT7JCL6styidLkPHA45MnQOnmcbt6jlq5UKSTz67LsmXAgMBAAECgYB+KbKnM5S0KRK0TtVn9T40fZasJj5pDgMRaBVx+6qdJyptlG+4SVGIIJ4Btw1SCMdfDcSnpC0jN8IUQuOFkJosu7N6iB4IxEIe7cDOWppO5fOAR51c9tU+Z6544RdEcL9+X4S2GfdT9IObriMrcg0q0PSnj73MpkKJ7jV0ybWNQQJBAL3AnHjgxFMYFInoagQ0yX1KMSQlv+OrbQbQoZYGsvaacRcVKa0wngeeF3lzFN2XxoMqUR1e5gbMiHJMTdjPKw0CQQC9erxjde5NYJtGtPYTx6bXL3zDKI/T82uqlCt3lMjTe+s73q9oUPFvBU0Zj/IWlqD0kgB1NETMJid1WPT+KI4zAkAdmKNPP0+f3kulzvhqO4mJ3z6W8sRhUGWrAHOToOvdBu3IueZMOx8K9R+YM9j3TysJXlpUiG68dL57hWdG/9kpAkBVXLcEg/uw5mXt69a0wIx8g0tMzLhHP3Hw7kHK5L+47ynh1gfmEhlC7/t1GbFx1bh7lk8YfkzEQCgkqMfuvKybAkAnkLilyXl60wLfeinuynte1IQGk5kNuH0/DaP89UkWnXIEfH4FBIXETIhSRXHYnDMEGfojuE3J25QZw2eKY8rq
    参与签名的数据: afterTaxMoney=1&batchNo=批次号&idCard=452626199212070014&name=张三&remark=备注&sumMoney=1&token=token&totalBillCount=1
    参与签名的数据的摘要(MD5值): 553218F911324C5F45282142C036778F
    数字签名: inrW4yFyEZrq1RNMVVaca5ImPiudcRsoCtlJCu8YADZ6mBLI5pHd9MkCElxNJCxFMbraEbXA8blhMbvdt3fqcgnJADIcy0xPVLLNXubCDes-brgmMBcmRLoEAFR_KZrDxj_5QzGZUekkiQxNh8_2emBxqvXjhUCJr-uwAzuwP9A
    签名验证结果:true
    
    展开全文
  • 基于FPGA的RSA数字签名

    2020-03-30 09:21:19
    RSA数字签名和RSA加密具体一定的对称性,两者大致内容是一致的,有关RSA加密的内容可以参见我的上一篇博客,这里大致说一下基于RSA的数字签名技术 简单可将RSA数字签名技术分成四个部分 1:生成私钥 d = (k(p-1)(q-1...
  • rsa数字签名c++图形化界面的实现方式,帮助密码学方面的同学用
  • RSA数字签名Java实现

    2014-11-05 14:05:48
    该源码分为两个包,一个rsa包,一个...SignatureData.java 实现数字签名 VerifySignature.java 实现数字签名验证,并含有主程序(main函数) cn.chd.david.utils BitByte.java 工具类,实现二进制流和十六进制流转换
  • RSA数字签名算法

    千次阅读 2016-12-08 21:18:22
    数字签名算法签名具有安全性、抗否认性的特点 ,数字签名——带有密钥(公钥、私钥)的消息摘要算法,用于验证数据完整性、认证数据来源、抗否认,...常用数字签名算法RSA、DSA、ECDSA。RSA算法包括MD、SHA经典算法两类
  • 数字签名如何工作 数字签名由两部分组成: 使用私钥从消息创建签名的算法; 允许任何人验证签名的算法; ...数字签名应该满足的要求 ...签名可信任,签名的识别应用相对容易,任何人都可以验证签名的...RSA数字签名的核...
  • C# 加签 验签 公钥 私钥 RSA数字签名

    千次阅读 2019-03-25 10:51:31
    * RSA数字签名-俗称加签验签:私钥加签,公钥验签。 java的公钥私钥是一串字符串,.net 公钥私钥是一串XML格式字符串,两者格式不是一致的,需要转换一下才能使用,具体请参考 JAVA和NET RSA密钥格式相互转换(公钥...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 35,436
精华内容 14,174
关键字:

rsa数字签名