zoukankan      html  css  js  c++  java
  • 简单RSA

    RSA加密需要用到质数

     1 # Prime Number Sieve
     2 # http://inventwithpython.com/hacking (BSD Licensed)
     3 
     4 import math
     5 
     6 
     7 def isPrime(num):
     8     # Returns True if num is a prime number, otherwise False.
     9 
    10     # Note: Generally, isPrime() is slower than primeSieve().
    11 
    12     # all numbers less than 2 are not prime
    13     if num < 2:
    14         return False
    15 
    16     # see if num is divisible by any number up to the square root of num
    17     for i in range(2, int(math.sqrt(num)) + 1):
    18         if num % i == 0:
    19             return False
    20     return True
    21 
    22 
    23 def primeSieve(sieveSize):
    24     # Returns a list of prime numbers calculated using
    25     # the Sieve of Eratosthenes algorithm.
    26 
    27     sieve = [True] * sieveSize
    28     sieve[0] = False # zero and one are not prime numbers
    29     sieve[1] = False
    30 
    31     # create the sieve
    32     for i in range(2, int(math.sqrt(sieveSize)) + 1):
    33         pointer = i * 2
    34         while pointer < sieveSize:
    35             sieve[pointer] = False
    36             pointer += i
    37 
    38     # compile the list of primes
    39     primes = []
    40     for i in range(sieveSize):
    41         if sieve[i] == True:
    42             primes.append(i)
    43 
    44     return primes
    primeSieve

    两个函数,第一个是常规的质数判断。第二个是埃拉托色尼筛选法

    方法:

    • (1)先把1删除(现今数学界1既不是质数也不是合数)
    • (2)读取队列中当前最小的数2,然后把2的倍数删去
    • (3)读取队列中当前最小的数3,然后把3的倍数删去
    • (4)读取队列中当前最小的数5,然后把5的倍数删去
    • (5)读取队列中当前最小的数7,然后把7的倍数删去
    • (6)如上所述直到需求的范围内所有的数均删除或读取

    检测较大质数——拉宾米勒质数检验,运用高等数学,且并非万无一失

     1 # Primality Testing with the Rabin-Miller Algorithm
     2 # http://inventwithpython.com/hacking (BSD Licensed)
     3 
     4 import random
     5 
     6 
     7 def rabinMiller(num):
     8     # Returns True if num is a prime number.
     9 
    10     s = num - 1
    11     t = 0
    12     while s % 2 == 0:
    13         # keep halving s until it is even (and use t
    14         # to count how many times we halve s)
    15         s = s // 2
    16         t += 1
    17 
    18     for trials in range(5): # try to falsify num's primality 5 times
    19         a = random.randrange(2, num - 1)
    20         v = pow(a, s, num)
    21         if v != 1: # this test does not apply if v is 1.
    22             i = 0
    23             while v != (num - 1):
    24                 if i == t - 1:
    25                     return False
    26                 else:
    27                     i = i + 1
    28                     v = (v ** 2) % num
    29     return True
    30 
    31 
    32 def isPrime(num):
    33     # Return True if num is a prime number. This function does a quicker
    34     # prime number check before calling rabinMiller().
    35 
    36     if (num < 2):
    37         return False # 0, 1, and negative numbers are not prime
    38 
    39     # About 1/3 of the time we can quickly determine if num is not prime
    40     # by dividing by the first few dozen prime numbers. This is quicker
    41     # than rabinMiller(), but unlike rabinMiller() is not guaranteed to
    42     # prove that a number is prime.
    43     lowPrimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]
    44 
    45     if num in lowPrimes:
    46         return True
    47 
    48     # See if any of the low prime numbers can divide num
    49     for prime in lowPrimes:
    50         if (num % prime == 0):
    51             return False
    52 
    53     # If all else fails, call rabinMiller() to determine if num is a prime.
    54     return rabinMiller(num)
    55 
    56 
    57 def generateLargePrime(keysize=1024):
    58     # Return a random prime number of keysize bits in size.
    59     while True:
    60         num = random.randrange(2**(keysize-1), 2**(keysize))
    61         if isPrime(num):
    62             return num
    rabinMiller

    简单RSA加密范例:

     1 # RSA Key Generator
     2 # http://inventwithpython.com/hacking (BSD Licensed)
     3 
     4 import random, sys, os, rabinMiller, cryptomath
     5 
     6 
     7 def main():
     8     # create a public/private keypair with 1024 bit keys
     9     print('Making key files...')
    10     makeKeyFiles('al_sweigart', 1024)
    11     print('Key files made.')
    12 
    13 def generateKey(keySize):
    14     # Creates a public/private key pair with keys that are keySize bits in
    15     # size. This function may take a while to run.
    16 
    17     # Step 1: Create two prime numbers, p and q. Calculate n = p * q.
    18     print('Generating p prime...')
    19     p = rabinMiller.generateLargePrime(keySize)
    20     print('Generating q prime...')
    21     q = rabinMiller.generateLargePrime(keySize)
    22     n = p * q
    23 
    24     # Step 2: Create a number e that is relatively prime to (p-1)*(q-1).
    25     print('Generating e that is relatively prime to (p-1)*(q-1)...')
    26     while True:
    27         # Keep trying random numbers for e until one is valid.
    28         e = random.randrange(2 ** (keySize - 1), 2 ** (keySize))
    29         if cryptomath.gcd(e, (p - 1) * (q - 1)) == 1:
    30             break
    31 
    32     # Step 3: Calculate d, the mod inverse of e.
    33     print('Calculating d that is mod inverse of e...')
    34     d = cryptomath.findModInverse(e, (p - 1) * (q - 1))
    35 
    36     publicKey = (n, e)
    37     privateKey = (n, d)
    38 
    39     print('Public key:', publicKey)
    40     print('Private key:', privateKey)
    41 
    42     return (publicKey, privateKey)
    43 
    44 
    45 def makeKeyFiles(name, keySize):
    46     # Creates two files 'x_pubkey.txt' and 'x_privkey.txt' (where x is the
    47     # value in name) with the the n,e and d,e integers written in them,
    48     # delimited by a comma.
    49 
    50     # Our safety check will prevent us from overwriting our old key files:
    51     if os.path.exists('%s_pubkey.txt' % (name)) or os.path.exists('%s_privkey.txt' % (name)):
    52         sys.exit('WARNING: The file %s_pubkey.txt or %s_privkey.txt already exists! Use a different name or delete these files and re-run this program.' % (name, name))
    53 
    54     publicKey, privateKey = generateKey(keySize)
    55 
    56     print()
    57     print('The public key is a %s and a %s digit number.' % (len(str(publicKey[0])), len(str(publicKey[1]))))
    58     print('Writing public key to file %s_pubkey.txt...' % (name))
    59     fo = open('%s_pubkey.txt' % (name), 'w')
    60     fo.write('%s,%s,%s' % (keySize, publicKey[0], publicKey[1]))
    61     fo.close()
    62 
    63     print()
    64     print('The private key is a %s and a %s digit number.' % (len(str(publicKey[0])), len(str(publicKey[1]))))
    65     print('Writing private key to file %s_privkey.txt...' % (name))
    66     fo = open('%s_privkey.txt' % (name), 'w')
    67     fo.write('%s,%s,%s' % (keySize, privateKey[0], privateKey[1]))
    68     fo.close()
    69 
    70 
    71 # If makeRsaKeys.py is run (instead of imported as a module) call
    72 # the main() function.
    73 if __name__ == '__main__':
    74     main()
    makeRsaKey
      1 # RSA Cipher
      2 # http://inventwithpython.com/hacking (BSD Licensed)
      3 
      4 import sys
      5 
      6 # IMPORTANT: The block size MUST be less than or equal to the key size!
      7 # (Note: The block size is in bytes, the key size is in bits. There
      8 # are 8 bits in 1 byte.)
      9 DEFAULT_BLOCK_SIZE = 128 # 128 bytes
     10 BYTE_SIZE = 256 # One byte has 256 different values.
     11 
     12 def main():
     13     # Runs a test that encrypts a message to a file or decrypts a message
     14     # from a file.
     15     filename = 'encrypted_file.txt' # the file to write to/read from
     16     mode = 'encrypt' # set to 'encrypt' or 'decrypt'
     17 
     18     if mode == 'encrypt':
     19         message = '''"Journalists belong in the gutter because that is where the ruling classes throw their guilty secrets." -Gerald Priestland "The Founding Fathers gave the free press the protection it must have to bare the secrets of government and inform the people." -Hugo Black'''
     20         pubKeyFilename = 'al_sweigart_pubkey.txt'
     21         print('Encrypting and writing to %s...' % (filename))
     22         encryptedText = encryptAndWriteToFile(filename, pubKeyFilename, message)
     23 
     24         print('Encrypted text:')
     25         print(encryptedText)
     26 
     27     elif mode == 'decrypt':
     28         privKeyFilename = 'al_sweigart_privkey.txt'
     29         print('Reading from %s and decrypting...' % (filename))
     30         decryptedText = readFromFileAndDecrypt(filename, privKeyFilename)
     31 
     32         print('Decrypted text:')
     33         print(decryptedText)
     34 
     35 
     36 def getBlocksFromText(message, blockSize=DEFAULT_BLOCK_SIZE):
     37     # Converts a string message to a list of block integers. Each integer
     38     # represents 128 (or whatever blockSize is set to) string characters.
     39 
     40     messageBytes = message.encode('ascii') # convert the string to bytes
     41 
     42     blockInts = []
     43     for blockStart in range(0, len(messageBytes), blockSize):
     44         # Calculate the block integer for this block of text
     45         blockInt = 0
     46         for i in range(blockStart, min(blockStart + blockSize, len(messageBytes))):
     47             blockInt += messageBytes[i] * (BYTE_SIZE ** (i % blockSize))
     48         blockInts.append(blockInt)
     49     return blockInts
     50 
     51 
     52 def getTextFromBlocks(blockInts, messageLength, blockSize=DEFAULT_BLOCK_SIZE):
     53     # Converts a list of block integers to the original message string.
     54     # The original message length is needed to properly convert the last
     55     # block integer.
     56     message = []
     57     for blockInt in blockInts:
     58         blockMessage = []
     59         for i in range(blockSize - 1, -1, -1):
     60             if len(message) + i < messageLength:
     61                 # Decode the message string for the 128 (or whatever
     62                 # blockSize is set to) characters from this block integer.
     63                 asciiNumber = blockInt // (BYTE_SIZE ** i)
     64                 blockInt = blockInt % (BYTE_SIZE ** i)
     65                 blockMessage.insert(0, chr(asciiNumber))
     66         message.extend(blockMessage)
     67     return ''.join(message)
     68 
     69 
     70 def encryptMessage(message, key, blockSize=DEFAULT_BLOCK_SIZE):
     71     # Converts the message string into a list of block integers, and then
     72     # encrypts each block integer. Pass the PUBLIC key to encrypt.
     73     encryptedBlocks = []
     74     n, e = key
     75 
     76     for block in getBlocksFromText(message, blockSize):
     77         # ciphertext = plaintext ^ e mod n
     78         encryptedBlocks.append(pow(block, e, n))
     79     return encryptedBlocks
     80 
     81 
     82 def decryptMessage(encryptedBlocks, messageLength, key, blockSize=DEFAULT_BLOCK_SIZE):
     83     # Decrypts a list of encrypted block ints into the original message
     84     # string. The original message length is required to properly decrypt
     85     # the last block. Be sure to pass the PRIVATE key to decrypt.
     86     decryptedBlocks = []
     87     n, d = key
     88     for block in encryptedBlocks:
     89         # plaintext = ciphertext ^ d mod n
     90         decryptedBlocks.append(pow(block, d, n))
     91     return getTextFromBlocks(decryptedBlocks, messageLength, blockSize)
     92 
     93 
     94 def readKeyFile(keyFilename):
     95     # Given the filename of a file that contains a public or private key,
     96     # return the key as a (n,e) or (n,d) tuple value.
     97     fo = open(keyFilename)
     98     content = fo.read()
     99     fo.close()
    100     keySize, n, EorD = content.split(',')
    101     return (int(keySize), int(n), int(EorD))
    102 
    103 
    104 def encryptAndWriteToFile(messageFilename, keyFilename, message, blockSize=DEFAULT_BLOCK_SIZE):
    105     # Using a key from a key file, encrypt the message and save it to a
    106     # file. Returns the encrypted message string.
    107     keySize, n, e = readKeyFile(keyFilename)
    108 
    109     # Check that key size is greater than block size.
    110     if keySize < blockSize * 8: # * 8 to convert bytes to bits
    111         sys.exit('ERROR: Block size is %s bits and key size is %s bits. The RSA cipher requires the block size to be equal to or greater than the key size. Either decrease the block size or use different keys.' % (blockSize * 8, keySize))
    112 
    113 
    114     # Encrypt the message
    115     encryptedBlocks = encryptMessage(message, (n, e), blockSize)
    116 
    117     # Convert the large int values to one string value.
    118     for i in range(len(encryptedBlocks)):
    119         encryptedBlocks[i] = str(encryptedBlocks[i])
    120     encryptedContent = ','.join(encryptedBlocks)
    121 
    122     # Write out the encrypted string to the output file.
    123     encryptedContent = '%s_%s_%s' % (len(message), blockSize, encryptedContent)
    124     fo = open(messageFilename, 'w')
    125     fo.write(encryptedContent)
    126     fo.close()
    127     # Also return the encrypted string.
    128     return encryptedContent
    129 
    130 
    131 def readFromFileAndDecrypt(messageFilename, keyFilename):
    132     # Using a key from a key file, read an encrypted message from a file
    133     # and then decrypt it. Returns the decrypted message string.
    134     keySize, n, d = readKeyFile(keyFilename)
    135 
    136 
    137     # Read in the message length and the encrypted message from the file.
    138     fo = open(messageFilename)
    139     content = fo.read()
    140     messageLength, blockSize, encryptedMessage = content.split('_')
    141     messageLength = int(messageLength)
    142     blockSize = int(blockSize)
    143 
    144     # Check that key size is greater than block size.
    145     if keySize < blockSize * 8: # * 8 to convert bytes to bits
    146         sys.exit('ERROR: Block size is %s bits and key size is %s bits. The RSA cipher requires the block size to be equal to or greater than the key size. Did you specify the correct key file and encrypted file?' % (blockSize * 8, keySize))
    147 
    148     # Convert the encrypted message into large int values.
    149     encryptedBlocks = []
    150     for block in encryptedMessage.split(','):
    151         encryptedBlocks.append(int(block))
    152 
    153     # Decrypt the large int values.
    154     return decryptMessage(encryptedBlocks, messageLength, (n, d), blockSize)
    155 
    156 
    157 # If rsaCipher.py is run (instead of imported as a module) call
    158 # the main() function.
    159 if __name__ == '__main__':
    160     main()
    rsaCipher
  • 相关阅读:
    程序员必须知道的10大基础实用算法及其讲解
    6 Java Exceptions that Haunts a Newbie Java Developer(Java菜鸟6种常见的异常)
    在线学习Java免费资源推荐(来自:importnew)
    Oracle触发器
    Oracle性能分析工具介绍及使用
    开口大数据闭口高并发,你们都是怎么回答
    Http中Get/Post请求区别
    快速排序算法
    MAG EF查询增加指定索引功能
    WEB传参
  • 原文地址:https://www.cnblogs.com/zhangzixian/p/10484906.html
Copyright © 2011-2022 走看看