Compare commits
No commits in common. 'main' and 'annn' 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,343 @@
|
||||
<?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="已成功实现在虚拟机和物理机之间运行">
|
||||
<change afterPath="$PROJECT_DIR$/ui.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/private.pem" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/public.pem" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/receiver_private.pem" beforeDir="false" afterPath="$PROJECT_DIR$/receiver_private.pem" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/receiver_public.pem" beforeDir="false" afterPath="$PROJECT_DIR$/receiver_public.pem" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/sender_private.pem" beforeDir="false" afterPath="$PROJECT_DIR$/sender_private.pem" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/sender_public.pem" beforeDir="false" afterPath="$PROJECT_DIR$/sender_public.pem" afterDir="false" />
|
||||
</list>
|
||||
<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">{
|
||||
"history": [
|
||||
{
|
||||
"assignee": "vernuser"
|
||||
}
|
||||
],
|
||||
"lastFilter": {
|
||||
"assignee": "vernuser"
|
||||
}
|
||||
}</component>
|
||||
<component name="GithubPullRequestsUISettings">{
|
||||
"selectedUrlAndAccountId": {
|
||||
"url": "https://github.com/vernuser/cryptography_homework.git",
|
||||
"accountId": "8b7e9b97-86ab-4db0-a673-929e037f7c36"
|
||||
}
|
||||
}</component>
|
||||
<component name="ProjectColorInfo">{
|
||||
"associatedIndex": 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"><![CDATA[{
|
||||
"keyToString": {
|
||||
"Python.client.executor": "Run",
|
||||
"Python.encryption_utils.executor": "Run",
|
||||
"Python.file_transfer.executor": "Run",
|
||||
"Python.generate_key.executor": "Run",
|
||||
"Python.generate_keys.executor": "Run",
|
||||
"Python.receiver.executor": "Run",
|
||||
"Python.sender.executor": "Run",
|
||||
"Python.server.executor": "Run",
|
||||
"Python.ui.executor": "Run",
|
||||
"Python.utils.executor": "Run",
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"RunOnceActivity.git.unshallow": "true",
|
||||
"git-widget-placeholder": "annn",
|
||||
"last_opened_file_path": "C:/Users/Asus/Desktop/烽台校园实习/交接资料/实验室仿真台攻击脚本/实验室仿真台攻击脚本/仿真台攻击脚本11.22",
|
||||
"node.js.detected.package.eslint": "true",
|
||||
"node.js.detected.package.tslint": "true",
|
||||
"node.js.selected.package.eslint": "(autodetect)",
|
||||
"node.js.selected.package.tslint": "(autodetect)",
|
||||
"nodejs_package_manager_path": "npm",
|
||||
"vue.rearranger.settings.migration": "true"
|
||||
}
|
||||
}]]></component>
|
||||
<component name="RunManager" selected="Python.ui">
|
||||
<configuration name="generate_key" 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$/generate_key.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="ui" 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$/ui.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.ui" />
|
||||
<item itemvalue="Python.generate_key" />
|
||||
<item itemvalue="Python.sender" />
|
||||
<item itemvalue="Python.server" />
|
||||
<item itemvalue="Python.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="581000" />
|
||||
<workItem from="1734607228597" duration="4000" />
|
||||
<workItem from="1734770663055" duration="28000" />
|
||||
<workItem from="1734779266249" duration="2176000" />
|
||||
</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>
|
||||
<task id="LOCAL-00006" summary="已成功实现在虚拟机和物理机之间运行">
|
||||
<option name="closed" value="true" />
|
||||
<created>1734489392435</created>
|
||||
<option name="number" value="00006" />
|
||||
<option name="presentableId" value="LOCAL-00006" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1734489392435</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="7" />
|
||||
<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/$ui.coverage" NAME="ui 覆盖结果" MODIFIED="1734781859043" 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="1734781683799" 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>
|
@ -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/.
|
@ -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,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,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-----
|
||||
MIIEpAIBAAKCAQEAl4H8ztB6F4Smewf7OUpgQCm2iJST9+X+odvFV9lkA0cU3HLb
|
||||
PV7O/dAC0jjVFOM1fNcklHxkJppH7kjJ31/XhfPvZpaShja6PZS2ffCPbQRBAcjh
|
||||
Ps0gwzZMKe3qwUBZCAducFtgi7BXvNhRNfOMufPnuzHx//XJReQzJ6Z747jticAT
|
||||
7nLIF2EM+vl24jsM1Gnm1LyMPV3gyxUamfqyLxyHr2WnqRNZs89CK4TnzrU9Jdw2
|
||||
Y5BzED9J7mDqOIOyDnzJ+9q/EN/ciOpnS04YkZH26nuVN90RHnp37MY9z7p3o8j8
|
||||
KRXir524o+UhBVgVkCS7zTmVorZsql7I2cx9GQIDAQABAoIBAAgL8QbbUkvmEWEV
|
||||
NlXZHU3BfJg6N+k7Ismq6yTBMktTeG6q5PnLi5FpMLUq+PPJvqeZb5Zsf6jMzRQ0
|
||||
c0OBvhsdrqUGsaDrzpScGnZYeYc2aiBAcIIa3lB8rxF50tvq4Uk7x86zQIHt+DYn
|
||||
hDMQcw48DFGU+f+rqKhyUcTOouOgJxyUr7z9gnz1OH2SQImiYaEuVceNULGrvGd/
|
||||
Zq1p7aqnm9WKwxX7oUXTBvx1s/EKsKPbWdLCNbHxLjYWfgEiErRi6ghLfGUhaKWu
|
||||
oSq38Cjqg9OCUmzjurfAvmZws4zCRthGuBW3EyAgHlt6S+JhoKoNg06zGso8uScq
|
||||
4+BrOCcCgYEAvlRpCZ7y4L8Nq4XEToK41nnsLUKgkXmQ5D1xUrz91F3SYMOdRa+M
|
||||
aQcHyhpyRI4mzAf/rxMBitXfTQzqzZkrX2QbAo450czOjHkdEKTRe8lfBXKnb0mz
|
||||
TAhpePDayENoPQeXH2BLUT8xMiJE/bCURGR4U5UPiH95X7ZzC9/3abMCgYEAy8h7
|
||||
KnXUXGZUJFycI7nPXCNY26OqatqKKYpWSNnzJRKO73JzP5SFmtUinASi9jB/m8Vz
|
||||
FWq5bcumS9KTLcAAjgeLWsRijvnBB2dmZYDq+TLxEfXDGr4lj/amOq87D7VjgVSV
|
||||
VQp1UpAGQfHdJFF72Lm4HnML1qC5z78aQRrgwAMCgYEAt+xUEJMEO8EEUcMTX5cd
|
||||
TU1GuLoQ9mOWa6kgcIbndygvG4kM2wF4WyoLEfeagrsnrLTyFNn1/JcOkaOw53tj
|
||||
mWvgWgjcwOv8kWycdLABK3D+HQKd4IJE/G2IlvGRSkMxYQCLvitMvTemr77EEq9n
|
||||
p+u7B3IdL5eXz7E83bXRndcCgYEAgxQKvW4bUe/0UYtMV+KOEfsejfEBjkfSNRQp
|
||||
miSvNHpyfGzG2u/C3KwZ3fdRhz/85QqlkvIaIhird/wT9YqaEMGjjpfhuYvG8Oc+
|
||||
wy2gdvigfefyPoJukOKbXAYY3GrVfXwVriTTAG9pxwM3NsQ/AFG9r8BargymWI3Y
|
||||
6mXKiVcCgYAp1OLouyd0RzAjazUHXjvo4/vrwLlKzZy/rKLHAxsyoNF4CI1x3SOQ
|
||||
QbmWRSFSm2Ki/iNEqI5YDirgNX953REQUUgY3vbYx0Uvjko/xqVqV2aUQRkqiuD8
|
||||
eWDP/MNdviC8Xh8EJxCNdbcRt54xa50XRzhcQysMPo7wBJ2PXoZ1gg==
|
||||
-----END RSA PRIVATE KEY-----
|
@ -0,0 +1,9 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAl4H8ztB6F4Smewf7OUpg
|
||||
QCm2iJST9+X+odvFV9lkA0cU3HLbPV7O/dAC0jjVFOM1fNcklHxkJppH7kjJ31/X
|
||||
hfPvZpaShja6PZS2ffCPbQRBAcjhPs0gwzZMKe3qwUBZCAducFtgi7BXvNhRNfOM
|
||||
ufPnuzHx//XJReQzJ6Z747jticAT7nLIF2EM+vl24jsM1Gnm1LyMPV3gyxUamfqy
|
||||
LxyHr2WnqRNZs89CK4TnzrU9Jdw2Y5BzED9J7mDqOIOyDnzJ+9q/EN/ciOpnS04Y
|
||||
kZH26nuVN90RHnp37MY9z7p3o8j8KRXir524o+UhBVgVkCS7zTmVorZsql7I2cx9
|
||||
GQIDAQAB
|
||||
-----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-----
|
||||
MIIEowIBAAKCAQEAvLvy6YiIfvCz+aF9gEkfHREjPPSPG6jI/hhSTiGG9i71rnCC
|
||||
rHFB3Nk0A1i/tv3rVn70O9W+jKroUNDNQaAoI3ytv0r+3iw/qS8S53ErGEV5Ms7Y
|
||||
MmgAkFTmQArWx9muD9JvLo1XFXvQFSIgtthdyqXC+SKnWsK9b/gXN7qVv/r5sR5A
|
||||
Mn067QZhVEc4cNfF0UEBS2+8UgxhH3PqbZzfV+cBfKBQ8JNWVgDmRSvKowQOQE87
|
||||
tMwTgsQKONuYFHtnzQ1Lo8gyF0f8PVRfln+hoj9WjvvCg0C9wBbfIuAxCgkqKEbb
|
||||
48KgUiNmT1YFJ3PaPAYjjchqQeFCT5CPqdC6jQIDAQABAoIBAARvgCKlXFxPX+DH
|
||||
IprUjuH4OHjmfLWh7MA8AopKM20g2IP2HBFrpxoqTDEVRt+6wxXQNKvkNsQ5yAm4
|
||||
2voRai5NGrdbFdrFEayc4tQu+VwVVecwAUqFFsOi8H5b7YUv/SYkRCg2z++SbnVG
|
||||
Bg5bXTALJpfncF4deKXVPFvJYMzspttNyE9lvoDL090/QsfITnOC6MNwu5EWwoH5
|
||||
zTJxxraiJpPnUiSA2S7w+EQV+WHgUCY2MFt4c1jIKfjtqB7g9wYQouKkVS3RzZoq
|
||||
iXqTS+avj5iMT+VRgxV5+WoRr+JXJf9aRmPtKqlFO4Jxt49EGLooBmw3Eq3WCItL
|
||||
gMUx1oECgYEAvy0anPGVLkDA1kRNsUCchKCnh2J4vWf8IZbS8OWSQm03Pyx26cUv
|
||||
AgeVtYXNqcCBP5f4X1Jg+jtwm7GwVQfD8CoMIoS0RKrEldFF9K03XfxI7mD+fjBo
|
||||
xAmcT1XHniMsAh6gT0bc7OAzt8wT7/e/cRSe/uBnSxROvCl7bezfgZECgYEA/Lre
|
||||
NlsyDEAuKgB/FRGnJDBWIlCULHLRfOi4dJi452JvgvWvxEa1DG2Hptbt+EfWuHIs
|
||||
Lf6hz+ePQLG022S8/KetkLwSqhohsOOhXoAuxf8j8ETUrMPHsaKUTjJNB6/0L1dt
|
||||
rKOxc0oQRuN0uH/f/uwbcKaOZ2Iypm5k+btTqz0CgYEArsSE98TCJC5+G2MFw2zV
|
||||
qUlU3adfyYcuL2a6IA8+zgsZ3l6/tqXUe36DlhZkFTMu9PvwyvN8REXig/LEyHb4
|
||||
4K0Put6mDcAvRuaxlSRk4T6pTYLOJH4MyGogw0Yf3qk4qhdlZhPaE5JCtVuTPmS2
|
||||
VqILV+W9iB1gfRNPCwborIECgYAIO7I3hRsJSSH33lJFhnCyfhygO43IMOlgL1iq
|
||||
+7qyVwOY+ZYDR+ZoBD1yEvhnqTd2hMmpqeztj/abve5NY2fAt1mxKF9XSUilsZS1
|
||||
NmnPq3MpRaTECBC+WbSJI5xczr+etzNsd1y1i8kh9hD8XbYXYOu37MUg2xMZVulV
|
||||
NWQRZQKBgASHsgW9kFtsNKqfvjFwCQlFF1o21kRcoUgmF1tFkhBxzWGUpeNJCLN5
|
||||
Y9eG9AY0FzlSG7ZfcMlSo0vZ5UZIciAx1Cyo943ArJSwo09DK7kVh2Hzo6lHMStg
|
||||
LP6/py2oIITlOfIx/x336EpKlDIpijKbhhxEHEfTnCra24f9hytP
|
||||
-----END RSA PRIVATE KEY-----
|
@ -0,0 +1,9 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvLvy6YiIfvCz+aF9gEkf
|
||||
HREjPPSPG6jI/hhSTiGG9i71rnCCrHFB3Nk0A1i/tv3rVn70O9W+jKroUNDNQaAo
|
||||
I3ytv0r+3iw/qS8S53ErGEV5Ms7YMmgAkFTmQArWx9muD9JvLo1XFXvQFSIgtthd
|
||||
yqXC+SKnWsK9b/gXN7qVv/r5sR5AMn067QZhVEc4cNfF0UEBS2+8UgxhH3PqbZzf
|
||||
V+cBfKBQ8JNWVgDmRSvKowQOQE87tMwTgsQKONuYFHtnzQ1Lo8gyF0f8PVRfln+h
|
||||
oj9WjvvCg0C9wBbfIuAxCgkqKEbb48KgUiNmT1YFJ3PaPAYjjchqQeFCT5CPqdC6
|
||||
jQIDAQAB
|
||||
-----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,158 @@
|
||||
import tkinter as tk
|
||||
from tkinter import filedialog, messagebox
|
||||
import os
|
||||
import subprocess
|
||||
from sender import send_file
|
||||
from receiver import receive_file
|
||||
from utils import load_key
|
||||
|
||||
class FileTransferApp:
|
||||
def __init__(self, root):
|
||||
self.root = root
|
||||
self.root.title("文件传输系统")
|
||||
self.root.geometry("800x900") # 增大窗口尺寸
|
||||
self.root.resizable(False, False) # 禁止调整窗口大小
|
||||
|
||||
# 设置窗口背景色
|
||||
self.root.configure(bg="#f5f5f5")
|
||||
|
||||
# 加载密钥
|
||||
self.sender_private_key = load_key('sender_private.pem')
|
||||
self.receiver_public_key = load_key('receiver_public.pem')
|
||||
self.receiver_private_key = load_key('receiver_private.pem')
|
||||
self.sender_public_key = load_key('sender_public.pem')
|
||||
|
||||
# 创建UI
|
||||
self.create_main_frame()
|
||||
|
||||
def create_main_frame(self):
|
||||
# 主界面,选择发送方或接收方
|
||||
self.main_frame = tk.Frame(self.root, bg="#f5f5f5")
|
||||
self.main_frame.pack(fill="both", expand=True)
|
||||
|
||||
self.selection_var = tk.StringVar(value="sender") # 默认选择发送方
|
||||
|
||||
# 选择发送方或接收方
|
||||
tk.Radiobutton(self.main_frame, text="我是发送方", variable=self.selection_var, value="sender", font=("Arial", 16),
|
||||
bg="#f5f5f5", command=self.switch_mode).pack(pady=20)
|
||||
tk.Radiobutton(self.main_frame, text="我是接收方", variable=self.selection_var, value="receiver", font=("Arial", 16),
|
||||
bg="#f5f5f5", command=self.switch_mode).pack(pady=20)
|
||||
|
||||
# 按钮:生成密钥
|
||||
tk.Button(self.main_frame, text="生成公钥/私钥对", font=("Arial", 16), bg="#8BC34A", fg="white", relief="raised", bd=4,
|
||||
width=20, height=2, command=self.generate_keys).pack(pady=20)
|
||||
|
||||
# 初始显示发送方界面
|
||||
self.sender_frame = None
|
||||
self.receiver_frame = None
|
||||
self.switch_mode()
|
||||
|
||||
def switch_mode(self):
|
||||
"""切换模式(发送方或接收方)"""
|
||||
# 清空当前界面
|
||||
if self.sender_frame:
|
||||
self.sender_frame.destroy()
|
||||
if self.receiver_frame:
|
||||
self.receiver_frame.destroy()
|
||||
|
||||
mode = self.selection_var.get()
|
||||
|
||||
if mode == "sender":
|
||||
self.create_sender_frame()
|
||||
elif mode == "receiver":
|
||||
self.create_receiver_frame()
|
||||
|
||||
def create_sender_frame(self):
|
||||
"""创建发送方界面"""
|
||||
self.sender_frame = tk.LabelFrame(self.main_frame, text="发送文件", padx=30, pady=30, bg="#ffffff", font=("Arial", 14, "bold"))
|
||||
self.sender_frame.pack(padx=30, pady=30, fill="both", expand=True)
|
||||
|
||||
self.filename_var = tk.StringVar()
|
||||
|
||||
# 选择文件按钮
|
||||
tk.Button(self.sender_frame, text="选择文件", command=self.select_file,
|
||||
font=("Arial", 16), bg="#4CAF50", fg="white", relief="raised", bd=4,
|
||||
width=20, height=3, activebackground="#45a049").pack(padx=10, pady=15)
|
||||
|
||||
# 显示文件路径
|
||||
self.filename_entry = tk.Entry(self.sender_frame, textvariable=self.filename_var, width=60, font=("Arial", 14), state='readonly', bd=3)
|
||||
self.filename_entry.pack(padx=10, pady=15)
|
||||
|
||||
# 输入接收方 IP 和端口
|
||||
tk.Label(self.sender_frame, text="接收方 IP:", font=("Arial", 14), bg="#ffffff").pack(pady=10)
|
||||
self.receiver_ip_entry = tk.Entry(self.sender_frame, width=40, font=("Arial", 14), bd=3)
|
||||
self.receiver_ip_entry.pack(pady=10)
|
||||
self.receiver_ip_entry.insert(0, "192.168.1.1")
|
||||
|
||||
tk.Label(self.sender_frame, text="接收方端口:", font=("Arial", 14), bg="#ffffff").pack(pady=10)
|
||||
self.receiver_port_entry = tk.Entry(self.sender_frame, width=40, font=("Arial", 14), bd=3)
|
||||
self.receiver_port_entry.pack(pady=10)
|
||||
self.receiver_port_entry.insert(0, "12345")
|
||||
|
||||
# 增大按钮大小
|
||||
send_button = tk.Button(self.sender_frame, text="发送文件", command=self.send_file,
|
||||
font=("Arial", 16), bg="#007BFF", fg="white", relief="raised", bd=4,
|
||||
width=25, height=3, activebackground="#0056b3")
|
||||
send_button.pack(padx=10, pady=30, fill='x')
|
||||
|
||||
def create_receiver_frame(self):
|
||||
"""创建接收方界面"""
|
||||
self.receiver_frame = tk.LabelFrame(self.main_frame, text="接收文件", padx=30, pady=30, bg="#ffffff", font=("Arial", 14, "bold"))
|
||||
self.receiver_frame.pack(padx=30, pady=30, fill="both", expand=True)
|
||||
|
||||
# 接收文件按钮
|
||||
receive_button = tk.Button(self.receiver_frame, text="接收文件", command=self.receive_file,
|
||||
font=("Arial", 16), bg="#FF5722", fg="white", relief="raised", bd=4,
|
||||
width=25, height=3, activebackground="#e64a19")
|
||||
receive_button.pack(padx=10, pady=30, fill='x')
|
||||
|
||||
def generate_keys(self):
|
||||
"""调用 generate_key.py 生成公钥和私钥"""
|
||||
try:
|
||||
# 使用 subprocess 调用 generate_key.py 生成密钥对
|
||||
subprocess.run(["python", "generate_key.py"], check=True)
|
||||
messagebox.showinfo("成功", "公钥和私钥已生成!")
|
||||
except subprocess.CalledProcessError as e:
|
||||
messagebox.showerror("错误", f"密钥生成失败:{e}")
|
||||
|
||||
def select_file(self):
|
||||
"""选择文件"""
|
||||
file_path = filedialog.askopenfilename()
|
||||
if file_path:
|
||||
self.filename_var.set(file_path)
|
||||
|
||||
def send_file(self):
|
||||
"""发送文件"""
|
||||
filename = self.filename_var.get()
|
||||
if not filename or not os.path.exists(filename):
|
||||
messagebox.showerror("错误", "请选择有效的文件!")
|
||||
return
|
||||
|
||||
receiver_ip = self.receiver_ip_entry.get()
|
||||
receiver_port = self.receiver_port_entry.get()
|
||||
|
||||
if not receiver_ip or not receiver_port:
|
||||
messagebox.showerror("错误", "请填写接收方的 IP 和端口!")
|
||||
return
|
||||
|
||||
try:
|
||||
# 调用 sender.py 中的 send_file 函数
|
||||
send_file(filename, receiver_ip, int(receiver_port), self.receiver_public_key, self.sender_private_key)
|
||||
messagebox.showinfo("成功", "文件发送成功!")
|
||||
except Exception as e:
|
||||
messagebox.showerror("错误", f"文件发送失败:{e}")
|
||||
|
||||
def receive_file(self):
|
||||
"""接收文件"""
|
||||
try:
|
||||
port = 12345
|
||||
# 调用 receiver.py 中的 receive_file 函数
|
||||
receive_file(port, self.receiver_private_key, self.sender_public_key)
|
||||
messagebox.showinfo("成功", "文件接收成功!")
|
||||
except Exception as e:
|
||||
messagebox.showerror("错误", f"文件接收失败:{e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
root = tk.Tk()
|
||||
app = FileTransferApp(root)
|
||||
root.mainloop()
|
@ -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…
Reference in new issue