ECC椭圆曲线加密.

ECC椭圆曲线加密

ECC也算是困扰已久的题型 现在通过几道题目 来初步了解一下这一类题型

有几种常见的算法下面先展开讲讲适用场景和使用方法discretelog(),smart sattackPohlig_Hellman

discrete_log()函数

discrete_log(a,base,ord,operation)

离散对数通用的算法,但不适用较大的数

参数说明:求解以base为底,a的对数;ord为base的阶,可以缺省,operation可以是+与*,默认为乘法

smart sattack

使用条件:模数P是质数,且E的阶(E上点的个数)等于P时可以使用

E=EllipticCurve(GF(p),[0,0,0,a,b])
E.order()=p

若输出是ture,则尝试打smart sattack

def SmartAttack(P,Q,p):
    E = P.curve()
    Eqp = EllipticCurve(Qp(p, 2), [ ZZ(t) + randint(0,p)*p for t in E.a_invariants() ])

    P_Qps = Eqp.lift_x(ZZ(P.xy()[0]), all=True)
    for P_Qp in P_Qps:
        if GF(p)(P_Qp.xy()[1]) == P.xy()[1]:
            break

    Q_Qps = Eqp.lift_x(ZZ(Q.xy()[0]), all=True)
    for Q_Qp in Q_Qps:
        if GF(p)(Q_Qp.xy()[1]) == Q.xy()[1]:
            break

    p_times_P = p*P_Qp
    p_times_Q = p*Q_Qp

    x_P,y_P = p_times_P.xy()
    x_Q,y_Q = p_times_Q.xy()

    phi_P = -(x_P/y_P)
    phi_Q = -(x_Q/y_Q)
    k = phi_Q/phi_P
    return ZZ(k)

l= SmartAttack(P, Q, p)
print(l)

Pohlig_Hellman

P是质数,且P-1包含的质因子较少&较小,如果P可被分解,即可尝试转化为CRT进行求解

factordb.com上网站试试是否可以分解

主要思想就是把一个模数转化为多组模数进行求解

def Pohlig_Hellman(n,P,Q):
    factors, exponents = zip(*factor(n))
    primes = [factors[i] ^ exponents[i] for i in range(len(factors))][:-1]
    print(primes)
    dlogs = []
    for fac in primes:
        t = int(int(P.order()) // int(fac))
        dlog = discrete_log(t*Q,t*P,operation="+")
        dlogs += [dlog]
        print("factor: "+str(fac)+", Discrete Log: "+str(dlog)) #calculates discrete logarithm for each prime order
    l = crt(dlogs,primes)
    return l

l = Pohlig_Hellman(n,P,Q)
print(l)

看看最经典的一题

[第五空间 2021]ecc

print 'Try to solve the 3 ECC'

from secret import flag
from Crypto.Util.number import *
assert(flag[:5]=='flag{')
flag = flag[5:-1]
num1 = bytes_to_long(flag[:7])
num2 = bytes_to_long(flag[7:14])
num3 = bytes_to_long(flag[14:])

def ECC1(num):
	p = 146808027458411567
	A = 46056180
	B = 2316783294673
	E = EllipticCurve(GF(p),[A,B])
	P = E.random_point() 
	Q = num*P
	print E
	print 'P:',P
	print 'Q:',Q

def ECC2(num):
	p = 1256438680873352167711863680253958927079458741172412327087203
	#import random
	#A = random.randrange(389718923781273978681723687163812)
	#B = random.randrange(816378675675716537126387613131232121431231)
	A = 377999945830334462584412960368612
	B = 604811648267717218711247799143415167229480
	E = EllipticCurve(GF(p),[A,B])
	P = E.random_point() 
	Q = num*P
	print E
	print 'P:',P
	print 'Q:',Q
	factors, exponents = zip(*factor(E.order()))
	primes = [factors[i] ^ exponents[i] for i in range(len(factors))][:-1]
	print primes
	dlogs = []
	for fac in primes:
		t = int(int(P.order()) / int(fac))
		dlog = discrete_log(t*Q,t*P,operation="+")
		dlogs += [dlog]
		print("factor: "+str(fac)+", Discrete Log: "+str(dlog)) #calculates discrete logarithm for each prime order
	print num
	print crt(dlogs,primes)



def ECC3(num):
	p = 0xd3ceec4c84af8fa5f3e9af91e00cabacaaaecec3da619400e29a25abececfdc9bd678e2708a58acb1bd15370acc39c596807dab6229dca11fd3a217510258d1b
	A = 0x95fc77eb3119991a0022168c83eee7178e6c3eeaf75e0fdf1853b8ef4cb97a9058c271ee193b8b27938a07052f918c35eccb027b0b168b4e2566b247b91dc07
	B = 0x926b0e42376d112ca971569a8d3b3eda12172dfb4929aea13da7f10fb81f3b96bf1e28b4a396a1fcf38d80b463582e45d06a548e0dc0d567fc668bd119c346b2
	E = EllipticCurve(GF(p),[A,B])
	P = E.random_point() 
	Q = num*P
	print E
	print 'P:',P
	print 'Q:',Q

ECC1(num1)
print '=============='
ECC2(num2)
print '=============='
ECC3(num3)

题目分为三块 对应着这ecc的三种不同的类型 同时也是三种不同的解法

首先先来学习第一块

输出的数据为

Elliptic Curve defined by y^2 = x^3 + 46056180*x + 2316783294673 over Finite Field of size 146808027458411567
P: (119851377153561800 : 50725039619018388 : 1)
Q: (22306318711744209 : 111808951703508717 : 1)

数比较小,可以直接使用_discretelog()求出

from Crypto.Util.number import *
p = 146808027458411567
a = 46056180
b = 2316783294673
E = EllipticCurve(GF(p),(a,b))
P = E(119851377153561800,50725039619018388)
Q = E(22306318711744209,111808951703508717)

num1 =  discrete_log(Q,P,operation = '+')
print(long_to_bytes(num1))
#13566003730592612
#b'025ab3d'

接下来是第二块

输出的数据为

Elliptic Curve defined by y^2 = x^3 + 377999945830334462584412960368612*x + 604811648267717218711247799143415167229480 over Finite Field of size 1256438680873352167711863680253958927079458741172412327087203
P: (550637390822762334900354060650869238926454800955557622817950 : 700751312208881169841494663466728684704743091638451132521079 : 1)
Q: (1152079922659509908913443110457333432642379532625238229329830 : 819973744403969324837069647827669815566569448190043645544592 : 1)

题目中提示了使用Pohlig_Hellman算法解密

p = 1256438680873352167711863680253958927079458741172412327087203
a = 377999945830334462584412960368612
b = 604811648267717218711247799143415167229480
E = EllipticCurve(GF(p),[a,b])
P = E(550637390822762334900354060650869238926454800955557622817950,700751312208881169841494663466728684704743091638451132521079)
Q = E(1152079922659509908913443110457333432642379532625238229329830,819973744403969324837069647827669815566569448190043645544592) 
# Q = k * P
n = E.order()

def Pohlig_Hellman(n,P,Q):
    factors, exponents = zip(*factor(n))
    primes = [factors[i] ^ exponents[i] for i in range(len(factors))][:-1]
    print(primes)
    dlogs = []
    for fac in primes:
        t = int(int(P.order()) // int(fac))
        dlog = discrete_log(t*Q,t*P,operation="+")
        dlogs += [dlog]
        print("factor: "+str(fac)+", Discrete Log: "+str(dlog)) #calculates discrete logarithm for each prime order
    num2 = crt(dlogs,primes)
    return num2

num2 = Pohlig_Hellman(n,P,Q)
print(num2)

'''
[2, 27, 5, 7, 212117, 302426983]
factor: 2, Discrete Log: 1
factor: 27, Discrete Log: 10
factor: 5, Discrete Log: 4
factor: 7, Discrete Log: 6
factor: 212117, Discrete Log: 126450
factor: 302426983, Discrete Log: 211578426
b'9-2521-'
'''

最后是第三块

输出内容如下

Elliptic Curve defined by y^2 = x^3 + 490963434153515882934487973185142842357175523008183292296815140698999054658777820556076794490414610737654365807063916602037816955706321036900113929329671*x + 7668542654793784988436499086739239442915170287346121645884096222948338279165302213440060079141960679678526016348025029558335977042712382611197995002316466 over Finite Field of size 11093300438765357787693823122068501933326829181518693650897090781749379503427651954028543076247583697669597230934286751428880673539155279232304301123931419
P: (10121571443191913072732572831490534620810835306892634555532657696255506898960536955568544782337611042739846570602400973952350443413585203452769205144937861 : 8425218582467077730409837945083571362745388328043930511865174847436798990397124804357982565055918658197831123970115905304092351218676660067914209199149610 : 1)
Q: (964864009142237137341389653756165935542611153576641370639729304570649749004810980672415306977194223081235401355646820597987366171212332294914445469010927 : 5162185780511783278449342529269970453734248460302908455520831950343371147566682530583160574217543701164101226640565768860451999819324219344705421407572537 : 1)

可以发现椭圆曲线阶数与p相等,用_smart sattack可以求出_

p = 0xd3ceec4c84af8fa5f3e9af91e00cabacaaaecec3da619400e29a25abececfdc9bd678e2708a58acb1bd15370acc39c596807dab6229dca11fd3a217510258d1b
A = 0x95fc77eb3119991a0022168c83eee7178e6c3eeaf75e0fdf1853b8ef4cb97a9058c271ee193b8b27938a07052f918c35eccb027b0b168b4e2566b247b91dc07
B = 0x926b0e42376d112ca971569a8d3b3eda12172dfb4929aea13da7f10fb81f3b96bf1e28b4a396a1fcf38d80b463582e45d06a548e0dc0d567fc668bd119c346b2
E = EllipticCurve(GF(p),[A,B])
P = E(10121571443191913072732572831490534620810835306892634555532657696255506898960536955568544782337611042739846570602400973952350443413585203452769205144937861,8425218582467077730409837945083571362745388328043930511865174847436798990397124804357982565055918658197831123970115905304092351218676660067914209199149610)
Q = E(964864009142237137341389653756165935542611153576641370639729304570649749004810980672415306977194223081235401355646820597987366171212332294914445469010927,5162185780511783278449342529269970453734248460302908455520831950343371147566682530583160574217543701164101226640565768860451999819324219344705421407572537)

def SmartAttack(P,Q,p):
    E = P.curve()
    Eqp = EllipticCurve(Qp(p, 2), [ ZZ(t) + randint(0,p)*p for t in E.a_invariants() ])

    P_Qps = Eqp.lift_x(ZZ(P.xy()[0]), all=True)
    for P_Qp in P_Qps:
        if GF(p)(P_Qp.xy()[1]) == P.xy()[1]:
            break

    Q_Qps = Eqp.lift_x(ZZ(Q.xy()[0]), all=True)
    for Q_Qp in Q_Qps:
        if GF(p)(Q_Qp.xy()[1]) == Q.xy()[1]:
            break

    p_times_P = p*P_Qp
    p_times_Q = p*Q_Qp

    x_P,y_P = p_times_P.xy()
    x_Q,y_Q = p_times_Q.xy()

    phi_P = -(x_P/y_P)
    phi_Q = -(x_Q/y_Q)
    k = phi_Q/phi_P
    return ZZ(k)

num3 = SmartAttack(P, Q, p)
print(num3)

"""
19597596255129283097357413993866074145935170485891892
b'4a81-9957-8c3381622434'

"""

拼接到得出答案NSSCTF{025ab3d9-2521-4a81-9957-8c3381622434}

[2023愚人杯]ecc_mini

from Crypto.Util.number import *
from secret import flag
flag=bytes_to_long(flag)
a =getPrime(256)
b =getPrime(256)
p =getPrime(256)
m1=int(str(flag)[:5])-4585
m2=int(str(flag)[5:])
#EllipticCurve([a1, a2, a3, a4, a6]) -- y^2+(a1)xy+(a3)y=x^3+(a2)x^2+(a4)x+(a6)
E = EllipticCurve(GF(p), [a, b])
X=E.lift_x(m1)
Y=7*X
m = E.random_point()
G = E.random_point()
k = getPrime(256)
K = k * G
r = getPrime(256)
c1 = m + r * K
c2 = r * G
w2=m[0]*m2
print(f"p = {p}")
print(f"a = {a}")
print(f"b = {b}")
print(f"k = {k}")
print(f"E = {E}")
print(f'Y = {Y}')
print(f"c1 = {c1}")
print(f"c2 = {c2}")
print(f"w2 = {w2}")
'''
p = 71397796933602469825964946338224836258949974632540581233301840806613437378503
a = 106105288190268015217241182934677375171023341761047638573248022053052499733117
b = 76170541771321874396004434442157725545076211607587599314450304327736999807927
k = 58155941823118858940343657716409231510854647214870891375273032214774400828217
E = Elliptic Curve defined by y^2 = x^3 + 34707491256665545391276236596452538912073367128507057339946181246439062354614*x + 4772744837719404570039488103932889286126236975047018081148463521123562429424 over Finite Field of size 71397796933602469825964946338224836258949974632540581233301840806613437378503
Y = (33237936857741483513705672980652927705102229733798436323453609986072499230366 : 52619411226266177137991318059937693955038910547834999771526408984808553907338 : 1)
c1 = (37414446283406201193977113266234367761786780230360175925999700345196415953455 : 17037724145039910971426670298726906655653040365428438334942732090559637519851 : 1)
c2 = (60560423732267272277570046154733119097475794979191838027420415113112056962844 : 54372226143125971429691267751299496959531971082475860532181772357190222938465 : 1)
w2 = 16315249811700998894876359855091105114973337718373913477026230968747515636405
'''

可以看到已经有部分的明文泄露了,所以其实我们可以对前面5个数位进行爆破,但是这里有两种爆破方式,一种是直接爆破解密,将合理的值输出,另一种是根据原文代码进行爆破,先找到正确的m1,再进行解密。

p = 71397796933602469825964946338224836258949974632540581233301840806613437378503
a = 106105288190268015217241182934677375171023341761047638573248022053052499733117
b = 76170541771321874396004434442157725545076211607587599314450304327736999807927
k = 58155941823118858940343657716409231510854647214870891375273032214774400828217
 
 
from Crypto.Util.number import *
 
 
E = EllipticCurve(GF(p), [a, b])
c1 = E(37414446283406201193977113266234367761786780230360175925999700345196415953455 , 17037724145039910971426670298726906655653040365428438334942732090559637519851)
c2 = E(60560423732267272277570046154733119097475794979191838027420415113112056962844 , 54372226143125971429691267751299496959531971082475860532181772357190222938465)
 
print(c1 - k * c2)
 
#m = (71304669061767049972885792894615651818794274529315856194992266286323237158881 : 10126770036343069593803252437914418057336213410278953515516757017939543175878 : 1)

获得m2

m0 = R(71304669061767049972885792894615651818794274529315856194992266286323237158881)
w2 = R(16315249811700998894876359855091105114973337718373913477026230968747515636405)
p = 71397796933602469825964946338224836258949974632540581233301840806613437378503
R = GF(p)
 
 
from Crypto.Util.number import *
 
 
E = EllipticCurve(GF(p), [a, b])
print(w2 // m0)
 
 
#m2 = 7196365442241205186856420688221367789171469258517476477

爆破m1

import libnum
m2 = int(7196365442241205186856420688221367789171469258517476477)
 
for i in range(10000,100000):
    m = m2 + i * 10 ** len(str(m2))
    try:
        flag = libnum.n2s(int(m)).decode()#可以用于滤除含不可见字符的字符串
        if '{' in flag: #保证flag形式合理
            print(flag)
    except:
        pass
 
 
#ctfshow{the_answer_is_it}

接下来就是pctf的题目了

好曲线

import hashlib
import os
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad

p=12506217790875063466368723611056175369923
A=12506217790875063466368723611052784275139
B=12506217790875063466368723533070038257347
F = FiniteField(p)
E = EllipticCurve(F,[A,B])
xP=7493372729181057645036574086903590138065
yP=359098907392057890604329721532958479621
P=[xP,yP]
P = E.point(P)
Q=k*P
Q = E.point(Q)
Q=[xQ,yQ]
#xQ=9505420031620208163682758801913524369821
#yQ=5460936589331844194485299189975059431657

key=hashlib.sha256(str(k).encode()).hexdigest()
key=bytes.fromhex(key)
iv=os.urandom(16)
cipher=AES.new(key[:16],AES.MODE_CBC,iv)
c=cipher.encrypt(pad(flag.encode(),AES.block_size))
print(iv)
print(c)
#b'f\xd0\x1e\xc7[P\x19\x07E\xe0[M;\x0f\xbc@'
#b'\x9b\x1b\xc1\x08\x18\x94\x90A\xad\xbd\x18U\x923Hy\xea\xfe~\x82\xb9\xa6}R\x0c\x19.-Ru\x11\x8d\x03\x9a\x97N\xb8:\xc5\x12\xc9\x95/\x88\xfa\x08\xb6\r'

同样这道题目前半部分打smart sattack 先得出k的值

p=12506217790875063466368723611056175369923
A=12506217790875063466368723611052784275139
B=12506217790875063466368723533070038257347
E = EllipticCurve(GF(p),[A,B])
xP=7493372729181057645036574086903590138065
yP=359098907392057890604329721532958479621
P=[xP,yP]
P = E.point(P)
xQ=9505420031620208163682758801913524369821
yQ=5460936589331844194485299189975059431657
Q=[xQ,yQ]
Q = E.point(Q)
def SmartAttack(P,Q,p):
    E = P.curve()
    Eqp = EllipticCurve(Qp(p, 2), [ ZZ(t) + randint(0,p)*p for t in E.a_invariants() ])

    P_Qps = Eqp.lift_x(ZZ(P.xy()[0]), all=True)
    for P_Qp in P_Qps:
        if GF(p)(P_Qp.xy()[1]) == P.xy()[1]:
            break

    Q_Qps = Eqp.lift_x(ZZ(Q.xy()[0]), all=True)
    for Q_Qp in Q_Qps:
        if GF(p)(Q_Qp.xy()[1]) == Q.xy()[1]:
            break

    p_times_P = p*P_Qp
    p_times_Q = p*Q_Qp

    x_P,y_P = p_times_P.xy()
    x_Q,y_Q = p_times_Q.xy()

    phi_P = -(x_P/y_P)
    phi_Q = -(x_Q/y_Q)
    k = phi_Q/phi_P
    return ZZ(k)

k = SmartAttack(P, Q, p)
print(k)

#11063983210789056064816501731025997778953

解出后就是AES CBC加密

from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
import hashlib
import os

k = 11063983210789056064816501731025997778953
iv = b'f\xd0\x1e\xc7[P\x19\x07E\xe0[M;\x0f\xbc@'  
ciphertext = b'\x9b\x1b\xc1\x08\x18\x94\x90A\xad\xbd\x18U\x923Hy\xea\xfe~\x82\xb9\xa6}R\x0c\x19.-Ru\x11\x8d\x03\x9a\x97N\xb8:\xc5\x12\xc9\x95/\x88\xfa\x08\xb6\r'

key = hashlib.sha256(str(k).encode()).digest()[:16]

cipher = AES.new(key, AES.MODE_CBC, iv)
decrypted_data = cipher.decrypt(ciphertext)


flag = unpad(decrypted_data, AES.block_size).decode('utf-8')
print("Decrypted flag:", flag)

然后是 ISCTF的题目

沉迷数学的小蓝鲨

# y² = x³ + 3x + 27 (mod p)
#
# Q(0xa61ae2f42348f8b84e4b8271ee8ce3f19d7760330ef6a5f6ec992430dccdc167, 0x8a3ceb15b94ee7c6ce435147f31ca8028d1dd07a986711966980f7de20490080)
#
# k= ?
#
# 最终flag请将解出k值的16进制转换为32位md5以ISCTF{}包裹提交

题目什么条件都没有 看着一头雾水

看看提示

HINT1
你验证过基点 G 真的在曲线上吗?(这只是个ez题,别想太复杂)

HINT2
G是这条曲线上的冒牌货,但代数运算不在乎,因为计算机可不是数学家

换句话说:题目给的点 G 虽然不满足曲线方程,但他们依旧用标准的椭圆曲线加法公式(带参数a=3)反复加倍,得到了Q=kG。

你不能直接用 Sage 的 EllipticCurve 构造这两个点(它会校验曲线方程),但你可以自己实现椭圆曲线的加法/倍乘,在程序中绕过合

性检查,直接用 BSGS 找出 k

这里引入了BSGS算法,先介绍一下 BSGS(baby-step giant-step),即大步小步算法。常用于求解离散对数问题

再然后可以看到题目少了条件 题目要求k值 所以点G理应是已知的 提示区块链常用参数 即可想到secp256k1 椭圆曲线的 生成元(Generator / Base Point)

开始解题

python

p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F  
a = 3  
  
G = (  
    0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798,  
    0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8  
)  
  
Q = (  
    0xa61ae2f42348f8b84e4b8271ee8ce3f19d7760330ef6a5f6ec992430dccdc167,  
    0x8a3ceb15b94ee7c6ce435147f31ca8028d1dd07a986711966980f7de20490080  
)  

O = None  
  
def inv_mod(x):  
    return pow(x % p, p - 2, p)  
  
def point_add(P, Q):  
    if P is None:  
        return Q  
    if Q is None:  
        return P
    x1, y1 = P  
    x2, y2 = Q  
    if x1 == x2 and (y1 + y2) % p == 0:  
        return None  
    if x1 == x2 and y1 == y2:  
        if y1 == 0:  
            return None  
        lam = (3 * x1 * x1 + a) * inv_mod(2 * y1) % p  
    else:  
        lam = (y2 - y1) * inv_mod(x2 - x1) % p  
    x3 = (lam * lam - x1 - x2) % p  
    y3 = (lam * (x1 - x3) - y1) % p  
    return (x3, y3)  
  
def scalar_mul(P, k):  
    R = None  
    T = P  
    while k:  
        if k & 1:  
            R = point_add(R, T)  
        T = point_add(T, T)  
        k >>= 1  
    return R  
  
# Baby-step Giant-step  
import math  
  
m = 1 << 16   
baby = {}  
R = None  
for j in range(m):  
    baby[R] = j  
    R = point_add(R, G)  
  
mG = scalar_mul(G, m)  
neg_mG = (mG[0], (-mG[1]) % p)  
  
gamma = Q  
for i in range(m + 1):  
    if gamma in baby:  
        k = i * m + baby[gamma]  
        print("找到 k =", k)  
        break  
    gamma = point_add(gamma, neg_mG)

要点说明:
point_add 和 scalar_mul 没有检查点是否在曲线上,使用相同的 a=3参数,复现题目里的 “代数运算”。

BSGS 中要减去 mG

m 的步长可以调大(比如改为 1 << 17),如果第一次没找到再扩大就好

babyECC2

from secret import flag
import random

bits = 64
p = random_prime(2^bits)
a = randint(1, bits)
b = randint(1, bits)
E = EllipticCurve(GF(p), [a, b])
g = E.random_element()

x = random_prime(2^16)
pk = x*g
k = randint(1, p-1)
kPoint = k*pk
kp = kPoint.xy()

c = []
for i in range(len(flag)):
  c.append( (ord(flag[i]) ^^ int(kp[i%2])) & 0xff )
c = bytes(c).hex()

print(p)
print(a)
print(b)
print(g)
#print(g.order())
print(c)

4698491801183562589
58
59
(2965797230620625775 : 4310564666276679314 : 1)
ac73a774a25bd512d543dc468542c9428141800dd041d043c918d112850dd515d6128214d1138211d71599

读题 一个正常的椭圆曲线 随机取点得到了g,pk 最终得到kp(某个点)

然后再看循环 将flag中的每一个字符转化ASC值再同kp异或(i为奇数则同x,为偶数则同y)

&0xff确保结果保持在 0–255(一个字节),通常用于防止溢出

最后转化为16进制

但是输出少了很多东西 没办法正着推出kp的两个值 因为题目是HSCTF 所以通过c先反推出x,y 随后即可正常求解

c = 'ac73a774a25bd512d543dc468542c9428141800dd041d043c918d112850dd515d6128214d1138211d71599'
c = bytes.fromhex(c)
key = [c[0]^ord('H'), c[1]^ord('S')]
print(key)
flag = ''
for i in range(len(c)):
    flag += chr(c[i] ^ key[i%2])
print(flag)
posted @ 2025-12-15 20:41  A1g3rn0n  阅读(135)  评论(0)    收藏  举报