PHP实现DSA签名,对接JAVA

1 篇文章 0 订阅

对接JAVA, 人家用的是DSA签名, 我先是百度, DSA签名, 信息真的是贼少, 少到了极点, 真的是贼少, 我搞了可久, 害, 走了弯路

一开始用的是phpseclib3的 DSA, 可是他们的DSA签名是自己直接生成了一个密钥对, 人家JAVA给我的有一个密钥了, 不行, 我就开始查非对称加密, 根据自己查到的东西(其实啥也没查到), 去找phpseclib里面的代码, 看看有没有load privateKey的方法, 找了一大圈, 自己照着上面疑似加载的代码写写, 还是不行, 和人家JAVA的对不上, 就放弃了这个, 到最后, 终于找到了, 我先截图, 后上代码, 嘿嘿嘿

这就是代码截图了, 秘钥是人家JAVA给我的, 自己可以先行百度一波 openssl_sign(), 下面上代码,

<?php

$data = 'woaiguohui666';

$res = getPrivateKey($privateKey);
if(!$res)
{
    echo '私钥无效';exit;
}
$sign = '';
$aa = openssl_sign($data, $sign, $res, OPENSSL_ALGO_DSS1); // openssl_sign 默认是OPENSSL_ALGO_SHA1, 但是咱们是DSA签名, 用这个OPENSSL_ALGO_DSS1, 主要还是看JAVA那边是什么签名, 对应的就行了
var_dump($aa);
echo '<br/>';
echo '加密: '.base64_encode($sign);
echo '<br/>';
$res2 = getPublicKey($publicKey);
if($rse2)
{
    echo '公钥无效';exit;
}
$res3 = openssl_verify($data, $sign, $res2, OPENSSL_ALGO_DSS1);
var_dump($res3);
echo '<br/>';
echo '解密: '.$data;

/**
 * 获取私钥,如是私钥可用,则返回资源对象,不合法返回false
 * @param string $strPrivateKey 密钥字符串
 * @return resource 资源对象
 */
function getPrivateKey($strPrivateKey){
    $pem = "-----BEGIN RSA PRIVATE KEY-----\n".
    wordwrap($strPrivateKey, 64, "\n", true).
    "\n-----END RSA PRIVATE KEY-----";
    
    $privateKey = openssl_pkey_get_private($pem);
    
    return $privateKey;
}


function getPublicKey($strPublicKey){
    $pem = "-----BEGIN PUBLIC KEY-----\n".
    wordwrap($strPublicKey, 64, "\n", true).
    "\n-----END PUBLIC KEY-----";
    
    $publicKey = openssl_pkey_get_public($pem);
    
    return $publicKey;
}

这上面的就是代码了, 公钥和私钥我就不发了, 毕竟是人家JAVA给我的, 露出来不咋好, 如果有需要的话直接私我, 我天天都登陆CSDN, 最多一天我就会回, 亲测可用, 下面就是结果, 我自己运行的结果

搞了一天多, 真累啊, 不过还好都出来了, 哈哈哈

小李大人

爱生活爱慧姐

2021-5-20 17:43:27

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
DSA(Digital Signature Algorithm)数字签名算法是一种公钥密码学签名算法,用于数字签名和身份验证。C++实现DSA签名算法需要用到大数运算库,可以使用GMP(GNU Multiple Precision Arithmetic Library)库。 以下是一个简单的代码示例,演示如何使用GMP库实现DSA签名算法: ```c++ #include <iostream> #include <gmpxx.h> #include <string.h> // DSA signature struct struct DSASignature { mpz_class r; mpz_class s; }; // DSA parameters struct struct DSAParams { mpz_class p; mpz_class q; mpz_class g; }; // Generate DSA parameters void generateDSAParams(DSAParams& params, int n) { mpz_class p, q, g, h; mpz_class zero = 0; // Generate prime number p mpz_urandomb(p.get_mpz_t(), gmp_randstate_t(NULL), n); mpz_nextprime(p.get_mpz_t(), p.get_mpz_t()); // Generate prime number q mpz_ui_pow_ui(q.get_mpz_t(), 2, 160); mpz_nextprime(q.get_mpz_t(), q.get_mpz_t()); // Calculate g while (true) { mpz_urandomm(h.get_mpz_t(), gmp_randstate_t(NULL), p.get_mpz_t()); mpz_powm(g.get_mpz_t(), h.get_mpz_t(), (p - 1) / q, p.get_mpz_t()); if (g != 1) { break; } } // Set parameters params.p = p; params.q = q; params.g = g; } // Generate DSA key pair void generateDSAKeyPair(mpz_class& privateKey, mpz_class& publicKey, DSAParams& params) { mpz_class zero = 0; // Generate private key do { mpz_urandomm(privateKey.get_mpz_t(), gmp_randstate_t(NULL), params.q.get_mpz_t()); } while (privateKey == zero); // Generate public key mpz_powm(publicKey.get_mpz_t(), params.g.get_mpz_t(), privateKey.get_mpz_t(), params.p.get_mpz_t()); } // Calculate DSA signature void calculateDSASignature(DSASignature& signature, const mpz_class& privateKey, const DSAParams& params, const unsigned char* message, size_t messageLength) { mpz_class k, r, s, h, x; mpz_class zero = 0; mpz_class one = 1; // Generate random number k do { mpz_urandomm(k.get_mpz_t(), gmp_randstate_t(NULL), params.q.get_mpz_t()); } while (k == zero); // Calculate r mpz_powm(r.get_mpz_t(), params.g.get_mpz_t(), k.get_mpz_t(), params.p.get_mpz_t()); r %= params.q; // Calculate s mpz_invert(x.get_mpz_t(), k.get_mpz_t(), params.q.get_mpz_t()); mpz_import(h.get_mpz_t(), messageLength, 1, sizeof(unsigned char), 0, 0, message); s = (x * (h + privateKey * r)) % params.q; // Set signature signature.r = r; signature.s = s; } // Verify DSA signature bool verifyDSASignature(const DSASignature& signature, const mpz_class& publicKey, const DSAParams& params, const unsigned char* message, size_t messageLength) { mpz_class w, u1, u2, v, h; mpz_class zero = 0; // Calculate w mpz_invert(w.get_mpz_t(), signature.s.get_mpz_t(), params.q.get_mpz_t()); // Calculate u1 mpz_import(h.get_mpz_t(), messageLength, 1, sizeof(unsigned char), 0, 0, message); u1 = (h * w) % params.q; // Calculate u2 u2 = (signature.r * w) % params.q; // Calculate v mpz_powm(v.get_mpz_t(), params.g.get_mpz_t(), u1.get_mpz_t(), params.p.get_mpz_t()); mpz_powm(u2.get_mpz_t(), publicKey.get_mpz_t(), u2.get_mpz_t(), params.p.get_mpz_t()); v = ((v * u2) % params.p) % params.q; // Verify signature return v == signature.r; } int main() { // Initialize GMP library mpz_class zero = 0; gmp_randstate_t randState; gmp_randinit_default(randState); gmp_randseed_ui(randState, time(NULL)); // Generate DSA parameters and key pair DSAParams params; generateDSAParams(params, 1024); mpz_class privateKey, publicKey; generateDSAKeyPair(privateKey, publicKey, params); // Sign message const char* message = "Hello, world!"; size_t messageLength = strlen(message); DSASignature signature; calculateDSASignature(signature, privateKey, params, (const unsigned char*)message, messageLength); // Verify signature bool verified = verifyDSASignature(signature, publicKey, params, (const unsigned char*)message, messageLength); if (verified) { std::cout << "Signature verified!" << std::endl; } else { std::cout << "Signature verification failed!" << std::endl; } // Clear GMP library gmp_randclear(randState); return 0; } ``` 在上面的代码中,我们使用了GMP库中的大数运算函数来计算DSA签名。我们首先生成DSA参数和密钥对,然后使用私钥对消息进行签名,并使用公钥来验证签名。如果签名成功,则输出“Signature verified!”,否则输出“Signature verification failed!”。 需要注意的是,在实际应用中,我们需要使用安全的随机数生成器来生成随机数,以增强DSA签名的安全性。此处我们使用了GMP库中的随机数生成函数,但在实际应用中,我们需要使用更为安全的随机数生成器来生成随机数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值