首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >椭圆曲线加密算法:256 256,曲线: P-256格式表示

椭圆曲线加密算法:256 256,曲线: P-256格式表示
EN

Security用户
提问于 2021-11-15 01:11:25
回答 1查看 2.4K关注 0票数 0

请帮助我理解发行人密钥结构之间的表示/连接,例如此处的表示/连接:

代码语言:javascript
复制
{
    "kty": "EC",
    "d": "6RDoFJrbnJ9WG0Y1CVXN0EnxbuQIgRMQfzFVKogbO6c",
    "use": "sig",
    "crv": "P-256",
    "x": "eIA4ZrdR7IOzYRqLER9_JIkfQCAeo1QI3VCEB7KaIow",
    "y": "WKPa365UL5KRw6OJJsZ3R_qFGQXCHg6eJe5Nzw526uQ",
    "alg": "ES256"
}

实际椭圆曲线Curve25519满足方程: y^2 = x^3+486662x^2+x

上面的x和y与我在这个方程中看到的x和y有关吗?如果是的话,究竟以什么方式?私钥"d“是如何连接到这一切的?曲线上的x+y与"d“有什么关系?那孩子(钥匙)呢?上面甚至没有显示。为什么它们都有43个字节长?

上面表示的格式是什么?

另外:我注意到QR代码有1776字节长:

代码语言:javascript
复制
shc:/56762909510950603511292437..............656  

它被翻译成长度为888的“数字”代码:

代码语言:javascript
复制
eyJ7aXAiOiKERUYiLREhbGciOiJFUzI1Ni.......xpW  

(如何将其转换成这样?)

这反过来又可以:

代码语言:javascript
复制
{"zip":"DEF","alg":"ES256","kid":"Nlewb7pUrU_f0tghYKc88uXM9U8en1gBu88rlufPUj7"}

X.509格式的私钥如下所示:

代码语言:javascript
复制
-----BEGIN PRIVATE KEY-----
MEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCDpEOgUmtucn1YbRjUJ
Vc3QSfFu5AiBExB/MVUqiBs7pw==
-----END PRIVATE KEY-----

为什么是92字节?

它们都是related....just,试图理解它们是如何相互转换的,特别是曲线方程?

谢谢史蒂夫

EN

回答 1

Security用户

回答已采纳

发布于 2021-11-15 02:18:02

椭圆曲线密码学是一个复杂的课题,解释它是如何工作的,远远超出了这个板上答案的范围。但是,我将参考Andrea的椭圆曲线密码学:一个温柔的游戏攻略,当我试图理解椭圆曲线密码学是如何工作的时,我找到了一个很好的来源,我认为这将为你回答大部分问题指明正确的方向。

在您发布的键中,d是私钥,以base64格式表示:6RDoFJrbnJ9WG0Y1CVXN0EnxbuQIgRMQfzFVKogbO6c"crv": "P-256"表示这是一条P256曲线。公钥是从私钥派生的。要获得公钥x和y值,必须使用P256椭圆曲线将私钥乘以“生成器点”。我们可以在这里找到P256椭圆曲线的生成点和参数:https://safecurves.cr.yp.to/equation.html

我上面提到的这篇文章的作者有一个python脚本,它在这里进行椭圆曲线运算:https://github.com/andreacorbellini/ecc/blob/master/scripts/ecdhe.py,我发现这个脚本在理解数学是如何工作和玩数学方面很有用。

为了了解您提供的密钥中的公钥x和y值是如何从私钥派生出来的,我们可以对Corbellini的脚本进行一些修改,使用P256曲线的参数,并使用6RDoFJrbnJ9WG0Y1CVXN0EnxbuQIgRMQfzFVKogbO6c作为私钥,如下所示:

代码语言:javascript
复制
import collections
import base64

EllipticCurve = collections.namedtuple('EllipticCurve', 'name p a b g n h')

#from https://safecurves.cr.yp.to/field.html:
curve = EllipticCurve(
    'P-256',
    # Field characteristic.
    p=0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff,
    # Curve coefficients.
    a=-3,
    b=41058363725152142129326129780047268409114441015993725554835256314039467401291,
    # Base point.
    g=(0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296,
       0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5),
    # Subgroup order.
    n=0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551,
    # Subgroup cofactor.
    h=1,

)


# Modular arithmetic ##########################################################

def inverse_mod(k, p):
    """Returns the inverse of k modulo p.

    This function returns the only integer x such that (x * k) % p == 1.

    k must be non-zero and p must be a prime.
    """
    if k == 0:
    raise ZeroDivisionError('division by zero')

    if k < 0:
    # k ** -1 = p - (-k) ** -1  (mod p)
    return p - inverse_mod(-k, p)

    # Extended Euclidean algorithm.
    s, old_s = 0, 1
    t, old_t = 1, 0
    r, old_r = p, k

    while r != 0:
    quotient = old_r // r
    old_r, r = r, old_r - quotient * r
    old_s, s = s, old_s - quotient * s
    old_t, t = t, old_t - quotient * t

    gcd, x, y = old_r, old_s, old_t

    assert gcd == 1
    assert (k * x) % p == 1

    return x % p


# Functions that work on curve points #########################################

def is_on_curve(point):
    """Returns True if the given point lies on the elliptic curve."""
    if point is None:
    # None represents the point at infinity.
    return True

    x, y = point

    return (y * y - x * x * x - curve.a * x - curve.b) % curve.p == 0


def point_neg(point):
    """Returns -point."""
    assert is_on_curve(point)

    if point is None:
    # -0 = 0
    return None

    x, y = point
    result = (x, -y % curve.p)

    assert is_on_curve(result)

    return result


def point_add(point1, point2):
    """Returns the result of point1 + point2 according to the group law."""
    assert is_on_curve(point1)
    assert is_on_curve(point2)

    if point1 is None:
    # 0 + point2 = point2
    return point2
    if point2 is None:
    # point1 + 0 = point1
    return point1

    x1, y1 = point1
    x2, y2 = point2

    if x1 == x2 and y1 != y2:
    # point1 + (-point1) = 0
    return None

    if x1 == x2:
    # This is the case point1 == point2.
    m = (3 * x1 * x1 + curve.a) * inverse_mod(2 * y1, curve.p)
    else:
    # This is the case point1 != point2.
    m = (y1 - y2) * inverse_mod(x1 - x2, curve.p)

    x3 = m * m - x1 - x2
    y3 = y1 + m * (x3 - x1)
    result = (x3 % curve.p,
          -y3 % curve.p)

    assert is_on_curve(result)

    return result


def scalar_mult(k, point):
    """Returns k * point computed using the double and point_add algorithm."""
    assert is_on_curve(point)

    if k % curve.n == 0 or point is None:
    return None

    if k < 0:
    # k * point = -k * (-point)
    return scalar_mult(-k, point_neg(point))

    result = None
    addend = point

    while k:
    if k & 1:
        # Add.
        result = point_add(result, addend)

    # Double.
    addend = point_add(addend, addend)

    k >>= 1

    assert is_on_curve(result)

    return result


private_key_hex='6RDoFJrbnJ9WG0Y1CVXN0EnxbuQIgRMQfzFVKogbO6c='
private_key=int.from_bytes(base64.b64decode(private_key_hex), 'big')

public_key = scalar_mult(private_key, curve.g)
(public_key_x, public_key_y)=public_key

print("private key:", base64.b64encode(private_key.to_bytes(32,'big')))
print("public key x:", base64.b64encode(public_key_x.to_bytes(32,'big')))
print("public key y:", base64.b64encode(public_key_y.to_bytes(32,'big')))

运行此脚本将生成:

代码语言:javascript
复制
private key: b'6RDoFJrbnJ9WG0Y1CVXN0EnxbuQIgRMQfzFVKogbO6c='
public key x: b'eIA4ZrdR7IOzYRqLER9/JIkfQCAeo1QI3VCEB7KaIow='
public key y: b'WKPa365UL5KRw6OJJsZ3R/qFGQXCHg6eJe5Nzw526uQ='

如您所见,脚本生成的公钥x和y值与您发布的键中的值相匹配。我希望这能帮到你。

票数 1
EN
页面原文内容由Security提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://security.stackexchange.com/questions/257080

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档