RSA中e和phi不互素问题

总述

g c d ( e , φ ( n ) ) gcd(e,\varphi(n)) gcd(e,φ(n))比较小时可以考虑iroot直接开根,当直接开根跑不出来时,考虑有限域内开方

g c d ( e , φ ( n ) ) gcd(e,\varphi(n)) gcd(e,φ(n))很大时,考虑AMM算法

类型一

e e e φ ( n ) \varphi(n) φ(n)不互素,但是 e e e p − 1 p-1 p1或者 q − 1 q-1 q1互素,转化到模 p p p或者模 q q q下求解

例题 (2023MoeCTF bad_E)

from Crypto.Util.number import *
p = getPrime(512)
q = getPrime(512)
e = 65537

print(p) # 6853495238262155391975011057929314523706159020478084061020122347902601182448091015650787022962180599741651597328364289413042032923330906135304995252477571
print(q) # 11727544912613560398705401423145382428897876620077115390278679983274961030035884083100580422155496261311510530671232666801444557695190734596546855494472819

with open("flag.txt","r") as fs:
    flag = fs.read().strip()

m = bytes_to_long(flag.encode())
c = pow(m,e,p*q)
print(c) # 63388263723813143290256836284084914544524440253054612802424934400854921660916379284754467427040180660945667733359330988361620691457570947823206385692232584893511398038141442606303536260023122774682805630913037113541880875125504376791939861734613177272270414287306054553288162010873808058776206524782351475805

exp

from Crypto.Util.number import *
p=6853495238262155391975011057929314523706159020478084061020122347902601182448091015650787022962180599741651597328364289413042032923330906135304995252477571
q=11727544912613560398705401423145382428897876620077115390278679983274961030035884083100580422155496261311510530671232666801444557695190734596546855494472819
e=65537
c = 63388263723813143290256836284084914544524440253054612802424934400854921660916379284754467427040180660945667733359330988361620691457570947823206385692232584893511398038141442606303536260023122774682805630913037113541880875125504376791939861734613177272270414287306054553288162010873808058776206524782351475805
n = p*q
# _gcd = gcd(e,(p-1)*(q-1)) # 65537
gcd_q = gcd(e,q-1) # 1

d = inverse(e,q-1)
m = pow(c,d,q)
print(long_to_bytes(int(m)))
# moectf{N0w_Y0U_hAve_kN0w_h0w_rsA_w0rks!_f!lP0iYlJf!M3ru}

因为gcd(e,phi)=e=665537很大,可以用AMM算法求解

exp2

# sagemanth
import random
import math
import time
from Crypto.Util.number import bytes_to_long,long_to_bytes
p = 0
#设置模数
def GF(a):
    global p
    p = a
#乘法取模
def g(a,b):
    global p
    return pow(a,b,p)


def AMM(x,e,p):
    GF(p)
    y = random.randint(1, p-1)
    while g(y, (p-1)//e) == 1:
        y = random.randint(1, p-1)
        print(y)
    print("find")
    #p-1 = e^t*s
    t = 1
    s = 0
    while p % e == 0:
        t += 1
        print(t)
    s = p // (e**t)
    print('e =',e)
    print('p =',p)
    print('s =',s)
    print('t =',t)
    # s|ralpha-1
    k = 1    
    while((s * k + 1) % e != 0):
        k += 1
    alpha = (s * k + 1) // e
    #计算a = y^s b = x^s h =1
    #h为e次非剩余部分的积
    a = g(y, (e ** (t - 1) ) * s)
    b = g(x, e * alpha - 1)
    c = g(y, s)
    h = 1
    #
    for i in range(1, t-1):
        d = g(b,e**(t-1-i))
        if d == 1:
            j = 0
        else:
            j = -math.log(d,a)
        b = b * (g(g(c, e), j))
        h = h * g(c, j)
        c = g(c, e)
    #return (g(x, alpha * h)) % p
    root = (g(x, alpha * h)) % p
    roots = set()
    for i in range(e):
        mp2 = root * g(a,i) %p
        assert(g(mp2, e) == x)
        roots.add(mp2)
    return roots
# def check(m):
#     if 'flag' in m:
#         print(m)
#         return True
#     else:
#         return False

p=6853495238262155391975011057929314523706159020478084061020122347902601182448091015650787022962180599741651597328364289413042032923330906135304995252477571
q=11727544912613560398705401423145382428897876620077115390278679983274961030035884083100580422155496261311510530671232666801444557695190734596546855494472819
e=65537
c = 63388263723813143290256836284084914544524440253054612802424934400854921660916379284754467427040180660945667733359330988361620691457570947823206385692232584893511398038141442606303536260023122774682805630913037113541880875125504376791939861734613177272270414287306054553288162010873808058776206524782351475805
n = p*q
mps = AMM(c,e,p)
for mpp in mps:
        solution = long_to_bytes(int(mpp))
        if b'moectf' in solution:
        #solution = int(mpp)
            print(solution)

类型二

_gcd=gcd(e,phi)=2比较小,直接iroote//_gcd次根

示例

from Crypto.Util.number import *
 
flag = b'NSSCTF{******}'
 
p = getPrime(512)
q = getPrime(512)
 
e = 65537*2
n = p*q 
m = bytes_to_long(flag)
c = pow(m, e, n)
 
print(f'p = {p}')
print(f'q = {q}')
print(f'e = {e}')
print(f'c = {c}')
 
'''
p = 9927950299160071928293508814174740578824022211226572614475267385787727188317224760986347883270504573953862618573051241506246884352854313099453586586022059
q = 9606476151905841036013578452822151891782938033700390347379468858357928877640534612459734825681004415976431665670102068256547092636766287603818164456689343
e = 131074
c = 68145285629092005589126591120307889109483909395989426479108244531402455690717006058397784318664114589567149811644664654952286387794458474073250495807456996723468838094551501146672038892183058042546944692051403972876692350946611736455784779361761930869993818138259781995078436790236277196516800834433299672560
'''

exp

import gmpy2
import libnum
 
p = 9927950299160071928293508814174740578824022211226572614475267385787727188317224760986347883270504573953862618573051241506246884352854313099453586586022059
q = 9606476151905841036013578452822151891782938033700390347379468858357928877640534612459734825681004415976431665670102068256547092636766287603818164456689343
e = 131074
c = 68145285629092005589126591120307889109483909395989426479108244531402455690717006058397784318664114589567149811644664654952286387794458474073250495807456996723468838094551501146672038892183058042546944692051403972876692350946611736455784779361761930869993818138259781995078436790236277196516800834433299672560
 
n = p*q
phi = (p-1)*(q-1)
_gcd = gmpy2.gcd(e, phi)
d = gmpy2.invert(e//_gcd, phi)
m_gcd = gmpy2.powmod(c, d, n)
m = gmpy2.iroot(m_gcd1, _gcd)    # 得到元组 (mpz(1920535408007397829480400151650246901210634018403879187581), True)
flag = libnum.n2s(int(m[0]))
print(flag)

类型三

gcd(e,phi)=16也比较小,但尝试iroot开根跑不出来,这时考虑有限域内开方来求解.

示例(2023 一带一路金砖国家 crypto1)

from Crypto.Util.number import *
from flag import flag
import gmpy2
assert(len(flag)==38)
flag = bytes_to_long(flag)

p = getPrime(512)
q = getPrime(512)

e = 304
enc = pow(flag,e,p*q)
print(p)
print(q)
print(enc)
#9794998439882070838464987778400633526071369507639213778760131552998185895297188941828281554258704149333679257014558677504899624597863467726403690826271979
#10684338300287479543408040458978465940026825189952497034380241358187629934633982402116457227553161613428839906159238238486780629366907463456434647021345729
#88310577537712396844221012233266891147970635383301697208951868705047581001657402229066444746440502616020663700100248617117426072580419555633169418185262898647471677640199331807653373089977785816106098591077542771088672088382667974425747852317932746201547664979549641193108900510265622890793400796486146522028

exp

from Crypto.Util.number import *
p = 9794998439882070838464987778400633526071369507639213778760131552998185895297188941828281554258704149333679257014558677504899624597863467726403690826271979
q = 10684338300287479543408040458978465940026825189952497034380241358187629934633982402116457227553161613428839906159238238486780629366907463456434647021345729
c = 88310577537712396844221012233266891147970635383301697208951868705047581001657402229066444746440502616020663700100248617117426072580419555633169418185262898647471677640199331807653373089977785816106098591077542771088672088382667974425747852317932746201547664979549641193108900510265622890793400796486146522028
e = 304
n = p*q

P.<a>=PolynomialRing(Zmod(p),implementation='NTL')
f=a^e-c
mps=f.monic().roots()

P.<a>=PolynomialRing(Zmod(q),implementation='NTL')
g=a^e-c
mqs=g.monic().roots()

flag=[]
for mpp in mps:
    x=mpp[0]
    for mqq in mqs:
        y=mqq[0]
        solution = CRT_list([int(x), int(y)], [p, q])
        flag.append(solution)
for i in flag:
    m=long_to_bytes(i)
    if b'flag'in m:
        print(m)
        
# flag{947b6543117e32730a93d1b43c98bc57}

注意到flag是38位,也就是304bit,而pq都是512bit,满足 m < p 或 者 m < q m<p或者m<q m<pm<q,可以转化到模p或者模q下求解,简化过程

g c d ( e , q − 1 ) = 16 gcd(e,q-1)=16 gcd(e,q1)=16

( m 16 ) q − 1 16 = c   m o d   q (m^{16})^{\frac{q-1}{16}}=c\textbf{ }mod \textbf{ }q (m16)16q1=c mod q

q − 1 16 \frac{q-1}{16} 16q1的逆元,计算 c d ′ = m 16   m o d   q c^{d{'}}=m^{16}\textbf{ }mod\textbf{ }q cd=m16 mod q

那么,就可以在模q有限域下开根求解

exp

from Crypto.Util.number import *
import gmpy2
p = 9794998439882070838464987778400633526071369507639213778760131552998185895297188941828281554258704149333679257014558677504899624597863467726403690826271979
q = 10684338300287479543408040458978465940026825189952497034380241358187629934633982402116457227553161613428839906159238238486780629366907463456434647021345729
c = 88310577537712396844221012233266891147970635383301697208951868705047581001657402229066444746440502616020663700100248617117426072580419555633169418185262898647471677640199331807653373089977785816106098591077542771088672088382667974425747852317932746201547664979549641193108900510265622890793400796486146522028
e = 304
n = p*q

_gcd = gmpy2.gcd(e,(q-1))
# print(_gcd) # 16
d = gmpy2.invert(e//_gcd,q-1)
m_16 = pow(c,d,q)

P.<x> = PolynomialRing(Zmod(q),implementation='NTL')
e = _gcd
f = x^e - m_16
mqs = f.monic().roots()
# print(len(mqs)) # 16

for i in mqs:
    flag = long_to_bytes(int(i[0]))
    if b'flag' in flag:
        print(flag)

补充

解释一下所用代码

P.<a>=PolynomialRing(Zmod(p),implementation='NTL')
f=a^e-c
mps=f.monic().roots()
定义了一个名为P的多项式环,a是这个环里面的变量,Zmod(p)是在模p下定义了一个整数环。多项式的每一个系数都是p的倍数,这样才能确保在模p下进行运算时不会出现浮点数。
参数implementation='NTL'指示SageMath使用NTL(Number Theory Library)作为该环的实现。
f=a^e-c定义了一个多项式
monic()是将多项式首一化
f.roots()得到方程的一个根的列表,该列表包含f(x)=a^e-c在模p意义下的所有根。
列表中的每个元素的格式为 (a,1),在此二元组表示中,1表示多重根,即该解在方程中的出现次数。

再详细看一下PolynomialRing()

PolynomialRingSageMath的一个函数,用于构建一个多项式环,看一个示例

# 创建一个多项式环,定义一个变量 'x'
R = PolynomialRing(QQ, 'x')

# 创建一个多项式
f = x^2 + 2*x + 1

# 可以对多项式进行代数运算,如加法、乘法
g = 2*x + 3

在上面的示例中,我们首先使用PolynomialRing()创建了一个多项式环R,其中QQ表示有理数域(可以使用其他域,如整数域ZZ或有限域GF(p))。然后,我们定义了多项式里的变量x,并使用这个环创建了一个多项式f

类型四

g c d ( e , φ ( n ) ) = e = 1009 gcd(e,\varphi(n))=e=1009 gcd(e,φ(n))=e=1009算是很大了,且 g c d ( e , p − 1 ) = g c d ( e , q − 1 ) = e = 1009 gcd(e,p-1)=gcd(e,q-1)=e=1009 gcd(e,p1)=gcd(e,q1)=e=1009.直接用AMM(很快,大概十几秒出结果)

之前做过的题,找不到附件了。。

from Crypto.Util.number import *
import random
import math

def onemod(e, q):
    p = random.randint(1, q-1)
    while(powmod(p, (q-1)//e, q) == 1):  # (r,s)=1
        p = random.randint(1, q)
    return p


def AMM_rth(o, r, q):  # r|(q-1)
    """
    x^r % q = o
    :param o:
    :param r:
    :param q:
    :return:
    """
    assert((q-1) % r == 0)
    p = onemod(r, q)

    t = 0
    s = q-1
    while(s % r == 0):
        s = s//r
        t += 1
    k = 1
    while((s*k+1) % r != 0):
        k += 1
    alp = (s*k+1)//r

    a = powmod(p, r**(t-1)*s, q)
    b = powmod(o, r*a-1, q)
    c = powmod(p, s, q)
    h = 1

    for i in range(1, t-1):
        d = powmod(int(b), r**(t-1-i), q)
        if d == 1:
            j = 0
        else:
            j = (-int(math.log(d, a))) % r
        b = (b*(c**(r*j))) % q
        h = (h*c**j) % q
        c = (c*r) % q
    result = (powmod(o, alp, q)*h)
    return result


def ALL_Solution(m, q, rt, cq, e):
    mp = []
    for pr in rt:
        r = (pr*m) % q
        # assert(pow(r, e, q) == cq)
        mp.append(r)
    return mp


def ALL_ROOT2(r, q):  # use function set() and .add() ensure that the generated elements are not repeated
    li = set()
    while(len(li) < r):
        p = powmod(random.randint(1, q-1), (q-1)//r, q)
        li.add(p)
    return li


def attack(p, q, e, check=None):
    cp = c % p
    cq = c % q

    mp = AMM_rth(cp, e, p)
    mq = AMM_rth(cq, e, q)

    rt1 = ALL_ROOT2(e, p)
    rt2 = ALL_ROOT2(e, q)

    amp = ALL_Solution(mp, p, rt1, cp, e)
    amq = ALL_Solution(mq, q, rt2, cq, e)

    if check is not None:
        j = 1
        t1 = invert(q, p)
        t2 = invert(p, q)
        for mp1 in amp:
            for mq1 in amq:
                j += 1
                if j % 1000000 == 0:
                    print(j)
                ans = (mp1 * t1 * q + mq1 * t2 * p) % (p * q)
                if check(ans):
                    return ans
    return amp, amq

def calc(mp, mq, e, p, q):
    i = 1
    j = 1
    t1 = invert(q, p)
    t2 = invert(p, q)
    for mp1 in mp:
        for mq1 in mq:
            j += 1
            if j % 1000000 == 0:
                print(j)
            ans = (mp1*t1*q+mq1*t2*p) % (p*q)
            if check(ans):
                return
    return

def check(m):
    try:
        a = long_to_bytes(m)
        if b'NSSCTF' in a:
            print(a)
            return True
        else:
            return False
    except:
        return False

if __name__ == '__main__':
    e = 1009
    n = 38041020633815871156456469733983765765506895617311762629687651104582466286930269704125415948922860928755218376007606985275046819516740493733602776653724917044661666016759231716059415706703608364873041098478331738686843910748962386378250780017056206432910543374411668835255040201640020726710967482627384460424737495938659004753604600674521079949545966815918391090355556787926276553281009472950401599151788863393804355849499551329
    c = 2252456587771662978440183865248648532442503596913181525329434089345680311102588580009450289493044848004270703980243056178363045412903946651952904162045861994915982599488021388197891419171012611795147125799759947942753772847866647801312816514803861011346523945623870123406891646751226481676463538137263366023714001998348605629756519894600802504515051642140147685496526829541501501664072723281466792594858474882239889529245732945
    p = 5220649501756432310453173296020153841505609640978826669340282938895377093244978215488158231209243571089268416199675077647719021740691293187913372884975853901554910056350739745148711689601574920977808625399309470283   
    q = 7286645200183879820325990521698389973072307061827784645416472106180161656047009812712987400850001340478084529480635891468153462119149259083604029658605921695587836792877281924620444742434168448594010024363257554563
    cp = c % p
    cq = c % q

    mp = AMM_rth(cp, e, p)
    mq = AMM_rth(cq, e, q)

    rt1 = ALL_ROOT2(e, p)
    rt2 = ALL_ROOT2(e, q)

    amp = ALL_Solution(mp, p, rt1, cp, e)
    amq = ALL_Solution(mq, q, rt2, cq, e)

    calc(amp, amq, e, p, q)

有限域开方也能跑出来(需要三至四分钟吧)

exp1

from Crypto.Util.number import *
e = 1009
n = 38041020633815871156456469733983765765506895617311762629687651104582466286930269704125415948922860928755218376007606985275046819516740493733602776653724917044661666016759231716059415706703608364873041098478331738686843910748962386378250780017056206432910543374411668835255040201640020726710967482627384460424737495938659004753604600674521079949545966815918391090355556787926276553281009472950401599151788863393804355849499551329
c = 2252456587771662978440183865248648532442503596913181525329434089345680311102588580009450289493044848004270703980243056178363045412903946651952904162045861994915982599488021388197891419171012611795147125799759947942753772847866647801312816514803861011346523945623870123406891646751226481676463538137263366023714001998348605629756519894600802504515051642140147685496526829541501501664072723281466792594858474882239889529245732945
p = 5220649501756432310453173296020153841505609640978826669340282938895377093244978215488158231209243571089268416199675077647719021740691293187913372884975853901554910056350739745148711689601574920977808625399309470283   
q = 7286645200183879820325990521698389973072307061827784645416472106180161656047009812712987400850001340478084529480635891468153462119149259083604029658605921695587836792877281924620444742434168448594010024363257554563

P.<a> = PolynomialRing(Zmod(p),implementation='NTL')
f = a^e - c
mps = f.monic().roots(multiplicities = False)
print(mps)

P.<a> = PolynomialRing(Zmod(q),implementation='NTL')
f = a^e - c
mqs = f.monic().roots(multiplicities = False)

for i in mps:
    for j in mqs:
        m = crt([int(i),int(j)],[p,q])
        flag = long_to_bytes(m)
        if b'NSSCTF' in flag:
            print(flag)

multiplicities = False不打印根的重数.

类型五(2023香山杯-list)

n = p r ∗ q n=p^{r}*q n=prq时,ephi不互素问题

附件

import os
import gmpy2
from Crypto.Util.number import *
import random
from secrets import flag
def pad(s,l):
    return s + os.urandom(l - len(s))
def gen():
    g = getPrime(8)
    while True:
        p = g * random.getrandbits(138) + 1
        if isPrime(p):
            break
    while True:
        q = g * random.getrandbits(138) + 1
        if isPrime(q):
            break
    N = p ** 5 * q
    phi = p ** 4 * (p - 1) * (q - 1)
    d = random.getrandbits(256)
    e = inverse(d, phi)
    E = e * g
    hint = gmpy2.gcd(E, phi)
    return N, E, hint

flag = pad(flag,64)
m = bytes_to_long(flag)
n,e,hint = gen()
c = pow(m,e,n)
print(f'hint = {hint}')
print(f'n = {n}')
print(f'e = {e}')
print(f'c = {c}')
# hint = 251
# n = 108960799213330048807537253155955524262938083957673388027650083719597357215238547761557943499634403020900601643719960988288543702833581456488410418793239589934165142850195998163833962875355916819854378922306890883033496525502067124670576471251882548376530637034077
# e = 3359917755894163258174451768521610910491402727660720673898848239095553816126131162471035843306464197912997253011899806560624938869918893182751614520610693643690087988363775343761651198776860913310798127832036941524620284804884136983215497742441302140070096928109039
# c = 72201537621260682675988549650349973570539366370497258107694937619698999052787116039080427209958662949131892284799148484018421298241124372816425123784602508705232247879799611203283114123802597553853842227351228626180079209388772101105198454904371772564490263034162

解题思路

先恢复pq

e ∗ d = 1   m o d   p h i , g c d ( e , p h i ) = 1 ⇒ e*d=1\textbf{ }mod\textbf{ }phi,gcd(e,phi)=1\Rightarrow ed=1 mod phi,gcd(e,phi)=1

e ∗ x − 1 = k ∗ p h i e*x-1=k*phi ex1=kphi
在多项式时间内求解上面方程(copper)求出d.
因 为 n = p r ∗ q , 所 以 g c d ( e ∗ x − 1 , n ) = g c d ( p r − 1 ∗ ( p − 1 ) ∗ ( q − 1 ) , p r ∗ q ) = p r − 1 因为n=p^{r}*q,所以gcd(e*x-1,n)=gcd(p^{r-1}*(p-1)*(q-1),p^{r}*q)=p^{r-1} n=prq,gcd(ex1,n)=gcd(pr1(p1)(q1),prq)=pr1
small_roots()r-1次方就能恢复 p

from gmpy2 import *
hint = 251
n = 108960799213330048807537253155955524262938083957673388027650083719597357215238547761557943499634403020900601643719960988288543702833581456488410418793239589934165142850195998163833962875355916819854378922306890883033496525502067124670576471251882548376530637034077
e = 3359917755894163258174451768521610910491402727660720673898848239095553816126131162471035843306464197912997253011899806560624938869918893182751614520610693643690087988363775343761651198776860913310798127832036941524620284804884136983215497742441302140070096928109039
c = 72201537621260682675988549650349973570539366370497258107694937619698999052787116039080427209958662949131892284799148484018421298241124372816425123784602508705232247879799611203283114123802597553853842227351228626180079209388772101105198454904371772564490263034162

P.<d> = PolynomialRing(Zmod(n))
f = e*d - 251
res = f.monic().small_roots(X = 2^256,beta = 0.4)

p_4 = gcd(int(f(res[0])),n)
p = iroot(p_4,4)[0]
q = n//p**4
print(f"p,q = {p},{q}")

接下来就是有限域开方的问题了

# sage
# 开251次方
from Crypto.Util.number import *
import itertools

hint = 251
n = 108960799213330048807537253155955524262938083957673388027650083719597357215238547761557943499634403020900601643719960988288543702833581456488410418793239589934165142850195998163833962875355916819854378922306890883033496525502067124670576471251882548376530637034077
e = 3359917755894163258174451768521610910491402727660720673898848239095553816126131162471035843306464197912997253011899806560624938869918893182751614520610693643690087988363775343761651198776860913310798127832036941524620284804884136983215497742441302140070096928109039
c = 72201537621260682675988549650349973570539366370497258107694937619698999052787116039080427209958662949131892284799148484018421298241124372816425123784602508705232247879799611203283114123802597553853842227351228626180079209388772101105198454904371772564490263034162

p,q=69367143733862710652791985332025152581988181 ,67842402383801764742069883032864699996366777

p_list = [p,q]
n_list = [p**5,q]
print(n_list)
# print(reduce((lambda x, y: x * y), n_list) - n)   # 0
# print(euler_phi(p_list[0])) # 直接求欧拉函数

res=[]

for pi in n_list:
    d = inverse(int(e//251),euler_phi(pi))     # 对n_listt 每一个 pi 求欧拉函数
    m = pow(c,d,pi)
    temp = (Zmod(pi)(m).nth_root(251, all=True))
    #print('temp =',temp) # 列表 251
    if temp is not None:
            res.append(temp)
    else:
            print("None")
   
for vc in itertools.product(*res):
    _c = [int(x) for x in vc]
    m = long_to_bytes(int(crt(_c, n_list)))
    if b"flag" in m:
        print(m)

# b'flag{4b68c7eece6be865f6da2a4323edd491}\x9d\xcf\xdc\xcb\xb8\xbdd\xec\xadh\xa6C\x99\xa0)7\xfb\x02\xba\x90q8\x10+\x7f}'
  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值