# Copyright 2011 Sybren A. Stüvel <sybren@stuvel.eu>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""RSA key generation code.
Create new keys with the newkeys() function. It will give you a PublicKey and a
PrivateKey object.
Loading and saving keys requires the pyasn1 module. This module is imported as
late as possible, such that other functionality will remain working in absence
of pyasn1.
.. note::
Storing public and private keys via the `pickle` module is possible.
However, it is insecure to load a key from an untrusted source.
The pickle module is not secure against erroneous or maliciously
constructed data. Never unpickle data received from an untrusted
or unauthenticated source.
"""
import logging
import typing
import warnings
import rsa.prime
import rsa.pem
import rsa.common
import rsa.randnum
import rsa.core
log = logging.getLogger(__name__)
DEFAULT_EXPONENT = 65537
class AbstractKey:
"""Abstract superclass for private and public keys."""
__slots__ = ('n', 'e')
def __init__(self, n: int, e: int) -> None:
self.n = n
self.e = e
@classmethod
def _load_pkcs1_pem(cls, keyfile: bytes) -> 'AbstractKey':
"""Loads a key in PKCS#1 PEM format, implement in a subclass.
:param keyfile: contents of a PEM-encoded file that contains
the public key.
:type keyfile: bytes
:return: the loaded key
:rtype: AbstractKey
"""
@classmethod
def _load_pkcs1_der(cls, keyfile: bytes) -> 'AbstractKey':
"""Loads a key in PKCS#1 PEM format, implement in a subclass.
:param keyfile: contents of a DER-encoded file that contains
the public key.
:type keyfile: bytes
:return: the loaded key
:rtype: AbstractKey
"""
def _save_pkcs1_pem(self) -> bytes:
"""Saves the key in PKCS#1 PEM format, implement in a subclass.
:returns: the PEM-encoded key.
:rtype: bytes
"""
def _save_pkcs1_der(self) -> bytes:
"""Saves the key in PKCS#1 DER format, implement in a subclass.
:returns: the DER-encoded key.
:rtype: bytes
"""
@classmethod
def load_pkcs1(cls, keyfile: bytes, format: str = 'PEM') -> 'AbstractKey':
"""Loads a key in PKCS#1 DER or PEM format.
:param keyfile: contents of a DER- or PEM-encoded file that contains
the key.
:type keyfile: bytes
:param format: the format of the file to load; 'PEM' or 'DER'
:type format: str
:return: the loaded key
:rtype: AbstractKey
"""
methods = {
'PEM': cls._load_pkcs1_pem,
'DER': cls._load_pkcs1_der,
}
method = cls._assert_format_exists(format, methods)
return method(keyfile)
@staticmethod
def _assert_format_exists(file_format: str, methods: typing.Mapping[str, typing.Callable]) \
-> typing.Callable:
"""Checks whether the given file format exists in 'methods'.
"""
try:
return methods[file_format]
except KeyError:
formats = ', '.join(sorted(methods.keys()))
raise ValueError('Unsupported format: %r, try one of %s' % (file_format,
formats))
def save_pkcs1(self, format: str = 'PEM') -> bytes:
"""Saves the key in PKCS#1 DER or PEM format.
:param format: the format to save; 'PEM' or 'DER'
:type format: str
:returns: the DER- or PEM-encoded key.
:rtype: bytes
"""
methods = {
'PEM': self._save_pkcs1_pem,
'DER': self._save_pkcs1_der,
}
method = self._assert_format_exists(format, methods)
return method()
def blind(self, message: int, r: int) -> int:
"""Performs blinding on the message using random number 'r'.
:param message: the message, as integer, to blind.
:type message: int
:param r: the random number to blind with.
:type r: int
:return: the blinded message.
:rtype: int
The blinding is such that message = unblind(decrypt(blind(encrypt(message))).
See https://en.wikipedia.org/wiki/Blinding_%28cryptography%29
"""
return (message * pow(r, self.e, self.n)) % self.n
def unblind(self, blinded: int, r: int) -> int:
"""Performs blinding on the message using random number 'r'.
:param blinded: the blinded message, as integer, to unblind.
:param r: the random number to unblind with.
:return: the original message.
The blinding is such that message = unblind(decrypt(blind(encrypt(message))).
See https://en.wikipedia.org/wiki/Blinding_%28cryptography%29
"""
return (rsa.common.inverse(r, self.n) * blinded) % self.n
class PublicKey(AbstractKey):
"""Represents a public RSA key.
This key is also known as the 'encryption key'. It contains the 'n' and 'e'
values.
Supports attributes as well as dictionary-like access. Attribute access is
faster, though.
>>> PublicKey(5, 3)
PublicKey(5, 3)
>>> key = PublicKey(5, 3)
>>> key.n
5
>>> key['n']
5
>>> key.e
3
>>> key['e']
3
"""
__slots__ = ('n', 'e')
def __getitem__(self, key: str) -> int:
return getattr(self, key)
def __repr__(self) -> str:
return 'PublicKey(%i, %i)' % (self.n, self.e)
def __getstate__(self) -> typing.Tuple[int, int]:
"""Returns the key as tuple for pickling."""
return self.n, self.e
def __setstate__(self, state: typing.Tuple[int, int]) -> None:
"""Sets the key from tuple."""
self.n, self.e = state
def __eq__(self, other: typing.Any) -> bool:
if other is None:
return False
if not isinstance(other, PublicKey):
return False
return self.n == other.n and self.e == other.e
def __ne__(self, other: typing.Any) -> bool:
return not (self == other)
def __hash__(self) -> int:
return hash((self.n, self.e))
@classmethod
def _load_pkcs1_der(cls, keyfile: bytes) -> 'PublicKey':
"""Loads a key in PKCS#1 DER format.
:param keyfile: contents of a DER-encoded file that contains the public
key.
:return: a PublicKey object
First let's construct a DER encoded key:
>>> import base64
>>> b64der = 'MAwCBQCNGmYtAgMBAAE='
>>> der = base64.standard_b64decode(b64der)
This loads the file:
>>> PublicKey._load_pkcs1_der(der)
PublicKey(2367317549, 65537)
"""
from pyasn1.codec.der import decoder
from rsa.asn1 import AsnPubKey
(priv, _) = decoder.decode(keyfile, asn1Spec=AsnPubKey())
return cls(n=int(priv['modulus']), e=int(priv['publicExponent']))
def _save_pkcs1_der(self) -> bytes:
"""Saves the public key in PKCS#1 DER format.
:returns: the DER-encoded public key.
:rtype: bytes
"""
from pyasn1.codec.der import encoder
from rsa.asn1 import AsnPubKey
# Create the ASN object
asn_key = AsnPubKey()
asn_key.setComponentByName('modulus', self.n)
asn_key.setComponentByName('publicExponent', self.e)
return encoder.encode(asn_key)
@classm
没有合适的资源?快使用搜索试试~ 我知道了~
daily_checkin.zip
共17个文件
py:17个
需积分: 5 4 下载量 188 浏览量
2022-01-07
18:14:45
上传
评论
收藏 33KB ZIP 举报
温馨提示
天翼云签到并领2次空间,2022年1月7日亲测可用 食用:https://blog.csdn.net/impish0/article/details/121439525
资源详情
资源评论
资源推荐
收起资源包目录
daily_checkin.zip (17个子文件)
MyTianYi.py 5KB
rsa
common.py 5KB
randnum.py 3KB
pem.py 4KB
pkcs1_v2.py 3KB
core.py 2KB
prime.py 5KB
cli.py 10KB
parallel.py 2KB
util.py 3KB
__init__.py 2KB
pkcs1.py 15KB
_compat.py 1KB
transform.py 2KB
key.py 25KB
asn1.py 2KB
index.py 382B
共 17 条
- 1
月清晖
- 粉丝: 2248
- 资源: 24
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- JSP-JTBC-CMS(SQLITE).rar
- MC3362和MC145151调频无线接收器的设计.pdf
- MiniRenamer-v100.0一款简单易用的批量文件重命名工具(已注册PRO版本).rar
- 小狐狸Ai系统 小狐狸ai付费创作系统V2.8.0 ChatGPT智能机器人
- 公孙离-内衣-肚兜.zipgsl
- 快慢指针判断链表是否有环-go 语言实现
- 学生成绩管理系统的设计与实现-收藏备用.pdf
- JSP+SQL网站流量统计管理系统(源代码+论文).rar
- IBM-PC-XT微机过程...道中模拟量数据的采集和处理.pdf
- JSP+SQL网上选课系统(源代码+论文+答辩PPT).rar
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0