Compare commits

..

No commits in common. 'main' and '216cbd4dd5a2564694821a95361ed37129a06caa' have entirely different histories.

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="MaterialThemeProjectNewConfig">
<option name="metadata">
<MTProjectMetadataState>
<option name="migrated" value="true" />
<option name="pristineConfig" value="false" />
<option name="userId" value="-255eb2d9:193864c0364:-7ffe" />
</MTProjectMetadataState>
</option>
</component>
</project>

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Black">
<option name="sdkName" value="Python 3.13" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.13" project-jdk-type="Python SDK" />
</project>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

@ -0,0 +1,321 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="b490c3d2-83ec-4ee0-b2e3-44d7951d4337" name="更改" comment="已成功实现在虚拟机和物理机之间运行" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="Python Script" />
</list>
</option>
</component>
<component name="Git.Settings">
<option name="PUSH_TAGS">
<GitPushTagMode>
<option name="argument" value="--tags" />
<option name="title" value="All" />
</GitPushTagMode>
</option>
<option name="RECENT_BRANCH_BY_REPOSITORY">
<map>
<entry key="$PROJECT_DIR$" value="master" />
</map>
</option>
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="GitHubPullRequestSearchHistory">{
&quot;history&quot;: [
{
&quot;assignee&quot;: &quot;vernuser&quot;
}
],
&quot;lastFilter&quot;: {
&quot;assignee&quot;: &quot;vernuser&quot;
}
}</component>
<component name="GithubPullRequestsUISettings">{
&quot;selectedUrlAndAccountId&quot;: {
&quot;url&quot;: &quot;https://github.com/vernuser/cryptography_homework.git&quot;,
&quot;accountId&quot;: &quot;8b7e9b97-86ab-4db0-a673-929e037f7c36&quot;
}
}</component>
<component name="ProjectColorInfo">{
&quot;associatedIndex&quot;: 6
}</component>
<component name="ProjectId" id="2q0CtQoODIzSL6TNpmKqHaR1R2h" />
<component name="ProjectLevelVcsManager" settingsEditedManually="true">
<ConfirmationsSetting value="2" id="Add" />
</component>
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent">{
&quot;keyToString&quot;: {
&quot;Python.client.executor&quot;: &quot;Run&quot;,
&quot;Python.encryption_utils.executor&quot;: &quot;Run&quot;,
&quot;Python.file_transfer.executor&quot;: &quot;Run&quot;,
&quot;Python.generate_key.executor&quot;: &quot;Run&quot;,
&quot;Python.generate_keys.executor&quot;: &quot;Run&quot;,
&quot;Python.receiver.executor&quot;: &quot;Run&quot;,
&quot;Python.sender.executor&quot;: &quot;Run&quot;,
&quot;Python.server.executor&quot;: &quot;Run&quot;,
&quot;Python.utils.executor&quot;: &quot;Run&quot;,
&quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
&quot;RunOnceActivity.git.unshallow&quot;: &quot;true&quot;,
&quot;git-widget-placeholder&quot;: &quot;annn&quot;,
&quot;last_opened_file_path&quot;: &quot;D:/college/大三/应用密码学课设&quot;,
&quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
&quot;node.js.detected.package.tslint&quot;: &quot;true&quot;,
&quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;,
&quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;,
&quot;nodejs_package_manager_path&quot;: &quot;npm&quot;,
&quot;vue.rearranger.settings.migration&quot;: &quot;true&quot;
}
}</component>
<component name="RunManager" selected="Python.sender">
<configuration name="encryption_utils" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
<module name="应用密码学课设" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/encryption_utils.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<configuration name="receiver" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
<module name="应用密码学课设" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/receiver.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<configuration name="sender" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
<module name="应用密码学课设" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/sender.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<configuration name="server" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
<module name="应用密码学课设" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/server.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<configuration name="utils" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
<module name="应用密码学课设" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/utils.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<recent_temporary>
<list>
<item itemvalue="Python.sender" />
<item itemvalue="Python.server" />
<item itemvalue="Python.utils" />
<item itemvalue="Python.receiver" />
<item itemvalue="Python.encryption_utils" />
</list>
</recent_temporary>
</component>
<component name="SharedIndexes">
<attachedChunks>
<set>
<option value="bundled-js-predefined-d6986cc7102b-e768b9ed790e-JavaScript-PY-243.21565.199" />
<option value="bundled-python-sdk-cab1f2013843-4ae2d6a61b08-com.jetbrains.pycharm.pro.sharedIndexes.bundled-PY-243.21565.199" />
</set>
</attachedChunks>
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="应用程序级" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="默认任务">
<changelist id="b490c3d2-83ec-4ee0-b2e3-44d7951d4337" name="更改" comment="" />
<created>1733790319291</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1733790319291</updated>
<workItem from="1733790320526" duration="16500000" />
<workItem from="1733816283165" duration="11000" />
<workItem from="1733816653982" duration="19000" />
<workItem from="1734342680147" duration="380000" />
<workItem from="1734406816783" duration="1550000" />
<workItem from="1734436439919" duration="90000" />
<workItem from="1734488993135" duration="326000" />
</task>
<task id="LOCAL-00001" summary="加了互传">
<option name="closed" value="true" />
<created>1733793465023</created>
<option name="number" value="00001" />
<option name="presentableId" value="LOCAL-00001" />
<option name="project" value="LOCAL" />
<updated>1733793465023</updated>
</task>
<task id="LOCAL-00002" summary="加了中文">
<option name="closed" value="true" />
<created>1733801157608</created>
<option name="number" value="00002" />
<option name="presentableId" value="LOCAL-00002" />
<option name="project" value="LOCAL" />
<updated>1733801157608</updated>
</task>
<task id="LOCAL-00003" summary="签名错误?">
<option name="closed" value="true" />
<created>1733810790769</created>
<option name="number" value="00003" />
<option name="presentableId" value="LOCAL-00003" />
<option name="project" value="LOCAL" />
<updated>1733810790769</updated>
</task>
<task id="LOCAL-00004" summary="已成功实现在虚拟机和物理机之间运行">
<option name="closed" value="true" />
<created>1733815825091</created>
<option name="number" value="00004" />
<option name="presentableId" value="LOCAL-00004" />
<option name="project" value="LOCAL" />
<updated>1733815825091</updated>
</task>
<task id="LOCAL-00005" summary="已成功实现在虚拟机和物理机之间运行">
<option name="closed" value="true" />
<created>1734489312302</created>
<option name="number" value="00005" />
<option name="presentableId" value="LOCAL-00005" />
<option name="project" value="LOCAL" />
<updated>1734489312302</updated>
</task>
<option name="localTasksCounter" value="6" />
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
<component name="Vcs.Log.Tabs.Properties">
<option name="TAB_STATES">
<map>
<entry key="MAIN">
<value>
<State>
<option name="FILTERS">
<map>
<entry key="branch">
<value>
<list>
<option value="annn" />
</list>
</value>
</entry>
</map>
</option>
</State>
</value>
</entry>
</map>
</option>
</component>
<component name="VcsManagerConfiguration">
<MESSAGE value="加了互传" />
<MESSAGE value="加了中文" />
<MESSAGE value="签名错误?" />
<MESSAGE value="已成功实现在虚拟机和物理机之间运行" />
<option name="LAST_COMMIT_MESSAGE" value="已成功实现在虚拟机和物理机之间运行" />
</component>
<component name="com.intellij.coverage.CoverageDataManagerImpl">
<SUITE FILE_PATH="coverage/$receiver.coverage" NAME="receiver 覆盖结果" MODIFIED="1734342809902" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
<SUITE FILE_PATH="coverage/$file_transfer.coverage" NAME="file_transfer 覆盖结果" MODIFIED="1733810226775" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
<SUITE FILE_PATH="coverage/$server.coverage" NAME="server 覆盖结果" MODIFIED="1734342831970" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
<SUITE FILE_PATH="coverage/$utils.coverage" NAME="utils 覆盖结果" MODIFIED="1734342818616" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
<SUITE FILE_PATH="coverage/$generate_key.coverage" NAME="generate_key 覆盖结果" MODIFIED="1733815607563" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
<SUITE FILE_PATH="coverage/$generate_keys.coverage" NAME="generate_keys 覆盖结果" MODIFIED="1733809016631" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
<SUITE FILE_PATH="coverage/$encryption_utils.coverage" NAME="encryption_utils 覆盖结果" MODIFIED="1734342806348" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
<SUITE FILE_PATH="coverage/$sender.coverage" NAME="sender 覆盖结果" MODIFIED="1734489006420" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
<SUITE FILE_PATH="coverage/$client.coverage" NAME="client 覆盖结果" MODIFIED="1733809932519" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
</component>
</project>

@ -0,0 +1 @@
166666

@ -1,73 +0,0 @@
Creative Commons Attribution-NoDerivs 1.0
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS DRAFT LICENSE DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM ITS USE.
License
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE IS PROHIBITED.
BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.
1. Definitions
a. "Collective Work" means a work, such as a periodical issue, anthology or encyclopedia, in which the Work in its entirety in unmodified form, along with a number of other contributions, constituting separate and independent works in themselves, are assembled into a collective whole. A work that constitutes a Collective Work will not be considered a Derivative Work (as defined below) for the purposes of this License.
b. "Derivative Work" means a work based upon the Work or upon the Work and other pre-existing works, such as a translation, musical arrangement, dramatization, fictionalization, motion picture version, sound recording, art reproduction, abridgment, condensation, or any other form in which the Work may be recast, transformed, or adapted, except that a work that constitutes a Collective Work will not be considered a Derivative Work for the purpose of this License.
c. "Licensor" means the individual or entity that offers the Work under the terms of this License.
d. "Original Author" means the individual or entity who created the Work.
e. "Work" means the copyrightable work of authorship offered under the terms of this License.
f. "You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation.
2. Fair Use Rights. Nothing in this license is intended to reduce, limit, or restrict any rights arising from fair use, first sale or other limitations on the exclusive rights of the copyright owner under copyright law or other applicable laws.
3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below:
a. to reproduce the Work, to incorporate the Work into one or more Collective Works, and to reproduce the Work as incorporated in the Collective Works;
b. to distribute copies or phonorecords of, display publicly, perform publicly, and perform publicly by means of a digital audio transmission the Work including as incorporated in Collective Works;
The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. All rights not expressly granted by Licensor are hereby reserved.
4. Restrictions. The license granted in Section 3 above is expressly made subject to and limited by the following restrictions:
a. You may distribute, publicly display, publicly perform, or publicly digitally perform the Work only under the terms of this License, and You must include a copy of, or the Uniform Resource Identifier for, this License with every copy or phonorecord of the Work You distribute, publicly display, publicly perform, or publicly digitally perform. You may not offer or impose any terms on the Work that alter or restrict the terms of this License or the recipients' exercise of the rights granted hereunder. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties. You may not distribute, publicly display, publicly perform, or publicly digitally perform the Work with any technological measures that control access or use of the Work in a manner inconsistent with the terms of this License Agreement. The above applies to the Work as incorporated in a Collective Work, but this does not require the Collective Work apart from the Work itself to be made subject to the terms of this License. If You create a Collective Work, upon notice from any Licensor You must, to the extent practicable, remove from the Collective Work any reference to such Licensor or the Original Author, as requested.
b. If you distribute, publicly display, publicly perform, or publicly digitally perform the Work or any Collective Works, You must keep intact all copyright notices for the Work and give the Original Author credit reasonable to the medium or means You are utilizing by conveying the name (or pseudonym if applicable) of the Original Author if supplied; the title of the Work if supplied. Such credit may be implemented in any reasonable manner; provided, however, that in the case of a Collective Work, at a minimum such credit will appear where any other comparable authorship credit appears and in a manner at least as prominent as such other comparable authorship credit.
5. Representations, Warranties and Disclaimer
a. By offering the Work for public release under this License, Licensor represents and warrants that, to the best of Licensor's knowledge after reasonable inquiry:
i. Licensor has secured all rights in the Work necessary to grant the license rights hereunder and to permit the lawful exercise of the rights granted hereunder without You having any obligation to pay any royalties, compulsory license fees, residuals or any other payments;
ii. The Work does not infringe the copyright, trademark, publicity rights, common law rights or any other right of any third party or constitute defamation, invasion of privacy or other tortious injury to any third party.
b. EXCEPT AS EXPRESSLY STATED IN THIS LICENSE OR OTHERWISE AGREED IN WRITING OR REQUIRED BY APPLICABLE LAW, THE WORK IS LICENSED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES REGARDING THE CONTENTS OR ACCURACY OF THE WORK.
6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, AND EXCEPT FOR DAMAGES ARISING FROM LIABILITY TO A THIRD PARTY RESULTING FROM BREACH OF THE WARRANTIES IN SECTION 5, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
7. Termination
a. This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Collective Works from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License.
b. Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above.
8. Miscellaneous
a. Each time You distribute or publicly digitally perform the Work or a Collective Work, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License.
b. If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
c. No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent.
d. This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You.
Creative Commons is not a party to this License, and makes no warranty whatsoever in connection with the Work. Creative Commons will not be liable to You or any party on any legal theory for any damages whatsoever, including without limitation any general, special, incidental or consequential damages arising in connection to this license. Notwithstanding the foregoing two (2) sentences, if Creative Commons has expressly identified itself as the Licensor hereunder, it shall have all rights and obligations of Licensor.
Except for the limited purpose of indicating to the public that the Work is licensed under the CCPL, neither party will use the trademark "Creative Commons" or any related trademark or logo of Creative Commons without the prior written consent of Creative Commons. Any permitted use will be in compliance with Creative Commons' then-current trademark usage guidelines, as may be published on its website or otherwise made available upon request from time to time.
Creative Commons may be contacted at http://creativecommons.org/.

@ -1,2 +0,0 @@
# file_tran

@ -0,0 +1 @@
{"nonce": "viRm4Dv0Hc1LnifER06rOw==", "ciphertext": "4Q==", "tag": "HD05+MIgwuWKStAA1DAelA==", "encrypted_key": "YkZ48DIhZzn4mjkzyajDZ8QCDvLFvp3+5N9stM4Bk8elaroz8hPY0UFfewxfYrj0Uz8jimYYANULsXE9itCHKWIaZC+XIIBfd13+eh4rDGuFipXy1ua6EwGDM8arGass4Prwy3G9pxX8j4iPKHWSgfSeqfKpMMBTVqadO5zPFXUOxqFjDOoKAO2lYusOdCIN5/X0sNQd7Bbc9RS59vG8N6yOGagwaATtEciSYr/4SVaqUTlyGiyegOb8OSoplj7jOyOvbUsaHEy3mVE7q992zImyPm+mvQjbWHS0gat+vzTMWRTVmbd8AdnXy3xnCDKhizsowKBtu6x4ksct1u9A5Q==", "signature": "ZUD0Nb2/4AAQRW1KQZIPrlZI7MtPbjM144TP3uIsBwtVTEO2Ew1g5cEb/ZAGSzIlyAiyqN/HVPYOKqpmzdLDHZtn2bQB6AjphLTgl0wwLjOhVc7QLHddWBQoetEhetSXdNZqCaQRb05p0TCA4J01fThVDbmonpEoAaR4xkDPw2zQKIFnYohkQY7xpqOFHfVCa4v/98LgUKkGkMOVXxLqvgVuUwmCWw+Or3WcIA9pxz4438v/VC1fuYGzk3bXHfnSoDstrXCQvfpsQ22O9vY3wwb2gxSxOHZWMMn8b542tzGAw9Ul/x8yCnjcdF1GxbEHoljgR5iSlqsJ85r2WNIo6A==", "filename": "1.txt"}

@ -0,0 +1,47 @@
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP, AES
from Crypto.Random import get_random_bytes
from Crypto.Signature import pkcs1_15
from Crypto.Hash import SHA256
class AsymmetricEncryption:
def __init__(self):
self.key_pair = RSA.generate(2048)
def get_public_key(self):
return self.key_pair.publickey()
def get_private_key(self):
return self.key_pair
def encrypt_with_public_key(self, data, public_key):
cipher_rsa = PKCS1_OAEP.new(public_key)
return cipher_rsa.encrypt(data)
def decrypt_with_private_key(self, encrypted_data):
cipher_rsa = PKCS1_OAEP.new(self.key_pair)
return cipher_rsa.decrypt(encrypted_data)
def sign_data(self, data):
h = SHA256.new(data)
signature = pkcs1_15.new(self.key_pair).sign(h)
return signature
def verify_signature(self, data, signature, public_key):
h = SHA256.new(data)
try:
pkcs1_15.new(public_key).verify(h, signature)
return True
except (ValueError, TypeError):
return False
class SymmetricEncryption:
def encrypt(self, data, key):
cipher_aes = AES.new(key, AES.MODE_GCM)
nonce = cipher_aes.nonce
ciphertext, tag = cipher_aes.encrypt_and_digest(data)
return nonce, ciphertext, tag
def decrypt(self, nonce, ciphertext, tag, key):
cipher_aes = AES.new(key, AES.MODE_GCM, nonce=nonce)
return cipher_aes.decrypt_and_verify(ciphertext, tag)

@ -0,0 +1,9 @@
from utils import generate_rsa_keypair, save_key
sender_private, sender_public = generate_rsa_keypair()
receiver_private, receiver_public = generate_rsa_keypair()
save_key('sender_private.pem', sender_private)
save_key('sender_public.pem', sender_public)
save_key('receiver_private.pem', receiver_private)
save_key('receiver_public.pem', receiver_public)

@ -0,0 +1,9 @@
-----BEGIN RSA PRIVATE KEY-----
MIIBPQIBAAJBAKJRCS1LQm9GAgZejtry1W0wMANwQQau01PeezV6DY7TOG+G08cv
boN4UaS5comyK7QKIr6WVi/4o+Pm5UcZsQ0CAwEAAQJAY0EgVnUd48Mwe8qYmmRB
hCoiQggDi12eVjvGpbXDPWF3yHX+mVbqrJY3oi9Ub9iJW8Lqw97DcBp/74fvvxd/
9QIjAPQTvQk8a7yTItR/Tyl/UStL0e+3KY6wuhWeEzACMV7JFcMCHwCqPtsRTG8e
ZBgat2p3ih2tkkO/XNshxOLibUZiIO8CIwCpH2A2HSK96OoSeiB9LZYtvPy78Jug
Hr7iKcU719kjx4wHAh8AqULQ/wPlPmv54yYUfkEdfKJ9JNcnLw3XHZPTdGCVAiJa
N3aZQDyYTX+/8V0E7vxaUlYJMgwXtXs+94qi25rsIWQr
-----END RSA PRIVATE KEY-----

@ -0,0 +1,4 @@
-----BEGIN RSA PUBLIC KEY-----
MEgCQQCiUQktS0JvRgIGXo7a8tVtMDADcEEGrtNT3ns1eg2O0zhvhtPHL26DeFGk
uXKJsiu0CiK+llYv+KPj5uVHGbENAgMBAAE=
-----END RSA PUBLIC KEY-----

@ -0,0 +1,55 @@
import json
import base64
import socket
from utils import aes_decrypt, rsa_decrypt, verify_signature, load_key
def receive_file(port, receiver_private_key, sender_public_key):
# 启动服务监听
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind(('', port))
s.listen(1)
print(f"接收方正在监听端口 {port}...")
conn, addr = s.accept()
print(f"来自 {addr} 的连接已建立!")
with conn:
# 接收数据
data = conn.recv(65536) # 最大接收 64KB 数据
data_packet = json.loads(data.decode('utf-8'))
# 解码 Base64 数据
nonce = base64.b64decode(data_packet['nonce'])
ciphertext = base64.b64decode(data_packet['ciphertext'])
tag = base64.b64decode(data_packet['tag'])
encrypted_key = base64.b64decode(data_packet['encrypted_key'])
signature = base64.b64decode(data_packet['signature'])
filename = data_packet['filename']
# 使用接收方私钥解密AES密钥
aes_key = rsa_decrypt(encrypted_key, receiver_private_key)
# 使用AES密钥解密文件内容
try:
file_data = aes_decrypt(nonce, ciphertext, tag, aes_key)
# 验证签名
if verify_signature(sender_public_key, file_data, signature):
print("签名验证成功,文件未被篡改!")
# 保存解密后的文件
with open(f"received_{filename}", 'wb') as f:
f.write(file_data)
print(f"文件已保存为 received_{filename}")
else:
print("签名验证失败,文件可能被篡改!")
except Exception as e:
print(f"文件解密或验证过程中出错:{e}")
if __name__ == "__main__":
# 加载密钥
receiver_private_key = load_key('receiver_private.pem')
sender_public_key = load_key('sender_public.pem')
# 监听端口
port = 12345
receive_file(port, receiver_private_key, sender_public_key)

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAqcmg7dhBByM+WbVKZ+5wfEO2eCRD0OhyjGZaVMEkfkv9jWon
H8nY9HT8lziJByNbs6ZbZnFkPoUxBi52938Bq2pTAJ3Z5l06qLfd6ryVdAO0IxZG
3+RZ2mfL4Jwg7jTrJ5ygRaiV/K8FjSzAkrEYHGwKc7mfxkyqmWbdq4f4ETBsiZ6d
SCoMqtDiSmeZ6/zjryAOGhqHDX/Zh3BqqOcapT1jm6Kf4Pc/BcpsHYQzblve3Frj
DWnQCzHGBN4AfQ8qmrQAXCaFa8xzAnzgvznVk411Bu2Rmsp1EWrBC5uY8x0IYF7b
MDi2/Bl5XAbPU32fCo141v2r/NeSV20p2k7DxwIDAQABAoIBAEY3qFHlBxOsHCue
gayU3DlQCaULHm7FyyXMaJw3ml+PDsfOuGp5oDuNLC9gBq+IjHKyIIev6my+yaUM
T1AQ2wBowvX00jpmoQ1IqULchhSKOZPvMRWECzL7jUIRX78T7JKfwFq+m3T6bxnR
Ab1I9zc96V6tzGmGqGEzvQYk/88fYglzuU8xz2uXiKj4/T8XnejuQj7hGKzPdKyf
zrDTbZ1vrFQutmgWMUMakAyFvn81KFzezhld53VgLSh+6k7tH8bxgzJ/b6BD74Wg
Na6XkM0xu2OamduNZczpBq2S3QkDPtihSfcZYUQ+z/VGLKsM2LkIGZ7VMgz447y4
TquhrDUCgYEAvqXVpYm9jPRWPGOMNA00wT3nbA3LjiddVtDFte2JN+JxiYRHvNtj
ALVZKifpKAmZSm6wVXWZ39LrGv4L0lNvKsGb3JM3bExJ4FmZsqpMzWCOkKM+Q9Cc
7tVwr2f13Gm2OYAn3dHpXo2knDtsDi2rwDmyAyOUEgANPFCj2v0NViMCgYEA4/05
Mawn0QTGsIhKHjtWWh3zOQUhroEPR7jqO19/BAE9srJEPuI6rOC4e6exiv/s81zR
qVsUQMHNfVaV7ka4yCmrUJHPYmvWNA9bZYSXH6AxMmd48SO9gAQx1nMR6YQrxZGW
GkzihxcGi7e8slXeJsCQ2tY0truJy2R4CYglTA0CgYEArhP8Zb/EnW0JRPDctzaL
whtFMYvTHwTgnIHa1ciEL8wLQbbQTijAWIg+V1jD83P4TVeOmSndi9sqI6Zuouje
K9tG9vxRcgiiuED4L4SCxlDxPC5ij0dv1EB+ORujClRYOF7FiCzAez64XJOBkdyv
48CKw4T8EgeMDlPPmgjP4aMCgYAs3atAtDFNt9Pl75wuYNz4dQZlRTZAohNAuQoX
Tw6u2hOrM9usSFblqH+FjhWpVf3qUmzMGClfKQRoUv7EWlSIx3J4M4mNQ81uh0sk
KjiXN64WzjgFtFPZennYSuLOgn0eryzL1i+KCCT4n9rZeX5zP9gByL+s6jEOvqHE
tm8ojQKBgQCxId3KRqYnmgFbefuuuqbonILGPNPZhkgRNT2l3J85v2IoofhZLsGB
AfS4mrkQ7UwzoaWdMOsfUYX/H0IWBs6blE/WL2OLPIfDWnmCTNftvbQouKhdMCwd
rOCwEZ3bH99O8rzvcdEmsgx+AK1g/3PpVFs4P8QGa0qNAIoORWKBbw==
-----END RSA PRIVATE KEY-----

@ -0,0 +1,9 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqcmg7dhBByM+WbVKZ+5w
fEO2eCRD0OhyjGZaVMEkfkv9jWonH8nY9HT8lziJByNbs6ZbZnFkPoUxBi52938B
q2pTAJ3Z5l06qLfd6ryVdAO0IxZG3+RZ2mfL4Jwg7jTrJ5ygRaiV/K8FjSzAkrEY
HGwKc7mfxkyqmWbdq4f4ETBsiZ6dSCoMqtDiSmeZ6/zjryAOGhqHDX/Zh3BqqOca
pT1jm6Kf4Pc/BcpsHYQzblve3FrjDWnQCzHGBN4AfQ8qmrQAXCaFa8xzAnzgvznV
k411Bu2Rmsp1EWrBC5uY8x0IYF7bMDi2/Bl5XAbPU32fCo141v2r/NeSV20p2k7D
xwIDAQAB
-----END PUBLIC KEY-----

@ -0,0 +1,53 @@
import os
import json
import base64
import socket
from utils import aes_encrypt, rsa_encrypt, generate_signature, load_key
def send_file(filename, receiver_ip, receiver_port, receiver_public_key, sender_private_key):
# 读取文件内容
with open(filename, 'rb') as f:
file_data = f.read()
# 生成随机AES密钥
aes_key = os.urandom(16)
# 加密文件
nonce, ciphertext, tag = aes_encrypt(file_data, aes_key)
# 使用接收方公钥加密AES密钥
encrypted_aes_key = rsa_encrypt(aes_key, receiver_public_key)
# 生成数字签名(针对原始文件内容)
signature = generate_signature(sender_private_key, file_data)
# 使用 Base64 对所有数据进行编码
data_packet = {
'nonce': base64.b64encode(nonce).decode(),
'ciphertext': base64.b64encode(ciphertext).decode(),
'tag': base64.b64encode(tag).decode(),
'encrypted_key': base64.b64encode(encrypted_aes_key).decode(),
'signature': base64.b64encode(signature).decode(),
'filename': os.path.basename(filename)
}
# 转换为 JSON 格式
data_packet_json = json.dumps(data_packet)
# 建立网络连接并发送数据
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((receiver_ip, receiver_port))
s.sendall(data_packet_json.encode('utf-8'))
print("文件已发送!")
if __name__ == "__main__":
# 加载密钥
receiver_public_key = load_key('receiver_public.pem')
sender_private_key = load_key('sender_private.pem')
# 文件路径和接收方信息
filename = '1.txt'
receiver_ip = '192.168.98.130' # 替换为接收方的IP地址
receiver_port = 12345
send_file(filename, receiver_ip, receiver_port, receiver_public_key, sender_private_key)

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAtSEr81A8CZPXnscsBgOkbQcrn3/JELmndlf2Ysez8sKCgz04
pB4XII0o7f2FZkDNLOu5fqs5OmSQd1IZReknGudcw5QJTUEvTKLzbkJNSJzhf0+k
H5yv9M3nS9DB6+VftjP0Hl84148UqpMUq71BygfwCFiUwgvUBbCfpO+gqth+oa38
wmcHQUeHYFhsJRGn2wI3URNuZIcJjOax2SCVAqRM/vyAS0Q7MSiGNV0BkVudhWkG
0/uaIvCRxO/F3TB9F4x5mHgCt1/cnHeQ4H8a7EsEmypSQ2oGB+oRt4GsvfFHwZGz
8uOUxQkGGCqNt1cLcHoOHuFJBHCSWwN/kF1feQIDAQABAoIBABjj/BQtnHJ8fI73
M9eHvJq294mtl8XSnW6n29XrN5FOpXy/dv8mm2r/uvYpdqF8mjVoF0+O3AhoNWoQ
QCTZS2RpEthViYmyQXu4kNdACTrHRD2ohhdKAuwTN4u1nlB6btKtBQj/cOI+aUqf
d6G6GkZXHOcotRiNY498nBOgUmXnqw+AMEDabzO2v2je+XBX5QCcHnfoTCsvlmqL
Am2Jr2Oq1pdO2kEDkDTPEJNdqNvVzVhcF5FSIR09jMsMEAUW9zyfcG+WvCWWDwC0
IcLSXmPYyfa2RNNaUoow3vTqFKBLt2KfE1FArwZkVIsVWwW+ucgEbvtXTbCOUrKl
oFyga9kCgYEAzWpRazlPsHHoYu/n40q8BdS/xWnchIlWgMKJCPXRDcJ4FLs3DpeU
tD/gyQCzZQ25sa8FpGhXvsaXibkY+f8TlFvUTNptP+5HRDfiZhJgCrdAiAQ8bu8U
u82nSf2w6paLmt7cR6yIEk/lLmHBsNICH2HvXk22HGOEFjQIV3Mh2/8CgYEA4bvY
grmCN6bIDq0Ws4KwcUnv7GqTS1BAsPr9YiZVst+wrNyozb9YZY913NwGcVJhebug
nXLP2OCQdc778lKvsGfYUoTfnlW9VSxhtC/YMUnQniVVmOwXuS+lf2rgdlxfX7qs
KHE5G1stbIIcDd6+ggIy7/OOLfCvcr6JXoNtpIcCgYEAgM5FJa43WRXkOX3j83Oe
eS2R3vFltLoFwxG5KiQyJaWm9KD8girstSZFBuVomFpF8bQlHpXLR7ZxuYuWrNSU
63e1pUdmMCtzBsTgM08caDvGvEOjvZAveSAY4V2x/TfPbJqImG0Imir9M9tawEy/
xfv8RC8Inb6NSfrwrB1mwvMCgYA1GvYyuuXRpeEG4t2mWaac4GIbYm9IlpbBjCq0
PoSG0m1EHZ1w2gU3z2pRDUpOuqzH8MY2hF41jY8uyAUp2x4OCEAyGaRqIY2rTgem
VmMsJUt5CRt8IH7sSDNNKJ2p+s1NPiNmWEyxDOBA2NM0yCRVfaLyJIBcenUsL3st
ywmuXQKBgDkgYTRIh3DtGZ9+NhjgkFJNwKHt3j5bq+7ySnDERBtJHcsKfQN/1f1f
JVbHAw6D4fJwp+F3ZMAWcgxHuuTSaus1i5Wb1vrvcEUzaYUjOkEDCV2Ow/Qb/Ssc
vSjFMSE4KhB4z3ry3UnK8dOtIVudBKNTAmEREx7H/ClDMm/3GEGn
-----END RSA PRIVATE KEY-----

@ -0,0 +1,9 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtSEr81A8CZPXnscsBgOk
bQcrn3/JELmndlf2Ysez8sKCgz04pB4XII0o7f2FZkDNLOu5fqs5OmSQd1IZRekn
Gudcw5QJTUEvTKLzbkJNSJzhf0+kH5yv9M3nS9DB6+VftjP0Hl84148UqpMUq71B
ygfwCFiUwgvUBbCfpO+gqth+oa38wmcHQUeHYFhsJRGn2wI3URNuZIcJjOax2SCV
AqRM/vyAS0Q7MSiGNV0BkVudhWkG0/uaIvCRxO/F3TB9F4x5mHgCt1/cnHeQ4H8a
7EsEmypSQ2oGB+oRt4GsvfFHwZGz8uOUxQkGGCqNt1cLcHoOHuFJBHCSWwN/kF1f
eQIDAQAB
-----END PUBLIC KEY-----

@ -0,0 +1,42 @@
import os
import json
from utils import aes_encrypt, rsa_encrypt, generate_signature, load_key
import base64
def send_file(filename, receiver_public_key, sender_private_key):
# 读取文件内容
with open(filename, 'rb') as f:
file_data = f.read()
# 生成随机AES密钥
aes_key = os.urandom(16)
# 加密文件
nonce, ciphertext, tag = aes_encrypt(file_data, aes_key)
# 使用接收方公钥加密AES密钥
encrypted_aes_key = rsa_encrypt(aes_key, receiver_public_key)
# 生成数字签名(针对原始文件内容)
signature = generate_signature(sender_private_key, file_data)
# 封装数据包
data_packet = {
'nonce': base64.b64encode(nonce).decode(),
'ciphertext': base64.b64encode(ciphertext).decode(),
'tag': base64.b64encode(tag).decode(),
'encrypted_key': base64.b64encode(encrypted_aes_key).decode(),
'signature': base64.b64encode(signature).decode(),
'filename': os.path.basename(filename)
}
# 保存数据包到文件
with open('data_packet.json', 'w') as f:
json.dump(data_packet, f)
print("文件已加密并发送。")
if __name__ == "__main__":
receiver_public_key = load_key('receiver_public.pem')
sender_private_key = load_key('sender_private.pem')
send_file('1.txt', receiver_public_key, sender_private_key)

@ -0,0 +1,70 @@
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP, AES
from Crypto.Signature import pkcs1_15
from Crypto.Hash import SHA256
import base64
import os
# 生成RSA密钥对
def generate_rsa_keypair():
key = RSA.generate(2048)
private_key = key.export_key()
public_key = key.publickey().export_key()
return private_key, public_key
# 保存密钥到文件
def save_key(filename, key):
with open(filename, 'wb') as f:
f.write(key)
# 加载密钥
def load_key(filename):
with open(filename, 'rb') as f:
return f.read()
# AES加密文件内容
def aes_encrypt(data, key):
cipher = AES.new(key, AES.MODE_EAX)
ciphertext, tag = cipher.encrypt_and_digest(data)
return cipher.nonce, ciphertext, tag
# AES解密文件内容
def aes_decrypt(nonce, ciphertext, tag, key):
cipher = AES.new(key, AES.MODE_EAX, nonce=nonce)
return cipher.decrypt_and_verify(ciphertext, tag)
# 使用RSA加密对称密钥
def rsa_encrypt(data, public_key):
cipher = PKCS1_OAEP.new(RSA.import_key(public_key))
return cipher.encrypt(data)
# 使用RSA解密对称密钥
def rsa_decrypt(data, private_key):
cipher = PKCS1_OAEP.new(RSA.import_key(private_key))
return cipher.decrypt(data)
# 生成数字签名
def generate_signature(private_key, data):
key = RSA.import_key(private_key)
h = SHA256.new(data)
signature = pkcs1_15.new(key).sign(h)
return signature
# 验证数字签名
def verify_signature(public_key, data, signature):
key = RSA.import_key(public_key)
h = SHA256.new(data)
try:
pkcs1_15.new(key).verify(h, signature)
return True
except (ValueError, TypeError):
return False
Loading…
Cancel
Save