我的编程空间,编程开发者的网络收藏夹
学习永远不晚

C#怎么生成putty格式的ppk文件

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

C#怎么生成putty格式的ppk文件

本篇内容主要讲解“C#怎么生成putty格式的ppk文件”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C#怎么生成putty格式的ppk文件”吧!

背景

2022国家级护网行动即将开启,根据阿里云给出的安全建议,需要将登陆Linux的方式改为密钥对方式。我这里使用的远程工具是自己开发的,能够同时管理Windows和Linux,但是以前不支持密钥对的登陆方式,所以需要改造一下。

护网行动是什么?护网行动从2016年开始,是一场由公安部组织的网络安全攻防演练,目的是针对全国范围的真实网络目标为对象的实战攻防活动,旨在发现、暴露和解决安全问题,检验我国各大企事业单位、部属机关的网络安全防护水平和应急处置能力。护网行动每年举办一次,为期2-3周。

我使用的远程工具 RDManager,这个工具访问Linux使用了putty,putty的密钥对登陆方式使用的是自有格式的ppk文件,但是阿里云上下载的是pem格式的密钥文件,所以需要将pem格式转换为ppk格式。

思路

putty本身提供了一个工具,可以将其他格式的密钥文件转换为自有的ppk文件,这个工具的名字是puttygen。在linux上可以通过命令进行转换,在Windows上则必须使用GUI工具手动操作,这多有不便。我期望的是能通过编程的方式进行这个转换,这样只需要在RDManger中上传pem文件,就可以自动转换为putty的ppk格式的文件,不需要再去使用puttygen。

首先查了下有没有现成的轮子,经过多次寻找,在Github上找到了一个项目:pem2ppk (https://github.com/akira345/pem2ppk),这个项目看名字就知道很贴合我的需求,它的主要功能就是读取pem文件,然后输出为ppk文件。我最终的解决方案主体也是从此而来。不过这个程序有两个问题:

  • 不是所有的pem文件都能转换成功,网上也是有人说成功了,有人说不行。

  • 不支持对密钥进行加密,别人拿走了这个ppk文件就可以直接使用。puttygen是有这个功能的。

实现

putty的源码官网上就可以下载到,不过我看的是一个几年前的版本:https://github.com/KasperDeng/putty,这个版本和新版本的主要逻辑都是一样的,搞懂C语言的若干函数和数据类型就很容易理解,而且旧版本更原始,没有那么多的抽象,反而更容易理解。

输出ppk内容不正确的问题

这个问题主要是由于填充(padding)使用不当造成的,pem2ppk项目在输出密钥的各个属性时都使用了前置填充,而putty并不是固定的都加了填充。

看putty的代码实现:https://github.com/KasperDeng/putty/blob/037a4ccb6e731fafc4cc77c0d16f80552fd69dce/putty-class="lazy" data-src/sshrsa.c#L654

    dlen = (bignum_bitcount(rsa->private_exponent) + 8) / 8;    plen = (bignum_bitcount(rsa->p) + 8) / 8;    qlen = (bignum_bitcount(rsa->q) + 8) / 8;    ulen = (bignum_bitcount(rsa->iqmp) + 8) / 8;    bloblen = 16 + dlen + plen + qlen + ulen;

这段代码是计算密钥的各个属性的值的字节数,然后用于初始化一个大的字节数组,将这些数据写进去。bignum_bitcount是计算值的比特位数,除以8就是得到字节数,为什么还要加8呢?这是因为C语言中除法的结果是向下取整的,比如数学计算结果是1.5,那么C语言中得到的就是1,为了不让任何一个比特丢失,所以这里加了一个8,预留好充足的空间。

再来看pem2ppk中的实现:https://github.com/akira345/pem2ppk/blob/d2baee08064953280984607d1e4ae1183127e5ad/PEM2PPK/PuttyKeyFileGenerator.cs#L24

private const int prefixSize = 4;private const int paddedPrefixSize = prefixSize + 1;byte[] publicBuffer = new byte[3 + keyType.Length + paddedPrefixSize + keyParameters.Exponent.Length +                                           paddedPrefixSize + keyParameters.Modulus.Length + 1];

这里keyParameters.Exponent和keyParameters.Modulus是公钥的两个属性,可以看到前边加了一个固定的长度paddedPrefixSize,这个paddedPrefixSize=prefixSize + 1,这里边的1就对应putty中的+8逻辑。

不过固定+1是有问题的,可以想一下C#和C语言在处理这些属性值时的差别。

在putty中如果数据比特数不能被8整除,那么+8之后再整除就可以得到正确的字节数,否则就会少1个字节;如果数据能被8整除,那么+8就会多1个空的字节,这个多的字节就是padding了。所以能被8整除的时候才会有这个padding。

在C#中开始处理的时候就已经都是字节了,所以C#中不需要处理位数不能被8整除的问题,但是需要在能被8整除的时候增加一个空字节,C#中如何判断数据的位数能被8整除呢?可以认为数据首byte的最高位是1的时候,比特数就能被8整数,此时最小二进制数是10000000,比它小的数就可以被舍弃掉至少1位。10000000也就是128,因此凡是大于等于这个数的都是能被8整数的,也就是需要padding的。

所以可以这样判断是否需要增加padding:https://gist.github.com/bosima/ee6630d30b533c7d7b2743a849e9b9d0#file-puttykeyfilegenerator-cs-L190

private static bool CheckIsNeddPadding(byte[] bytes){return bytes[0] >= 128;}private static int GetPrefixSize(byte[] bytes){return CheckIsNeddPadding(bytes) ? paddedPrefixSize : prefixSize;}

实现ppk加密

pem2ppk项目中没有对key进行加密的实现,网上也没有找到C#的源代码可以实现这个功能。但是这个功能很关键,在RDManager中所有的密码都是加密处理的,这样服务器账号落盘的时候安全性才能有比较好的保障,但是阿里云导出的pem是没有加密的,虽然puttygen也可以给pem加密,但是还不是不能将加密以编程的方式集成到RDManager中。

解决这个问题的方式还是搬运putty的实现方式,将C语言的实现转换为C#的实现。其中有两个关键的处理:一是要在计算Private-MAC的值时给私钥增加padding,二是使用AES256进行加密处理。至于putty为什么要这样处理,我没有研究,只是照搬过来。

主要看下AES256加密的处理,有些参数很关键:

byte[] passKey = new byte[40];...byte[] iv = new byte[16];byte[] aesKey = new byte[32];Buffer.BlockCopy(passKey, 0, aesKey, 0, 32);using (RijndaelManaged rijalg = new RijndaelManaged()){rijalg.BlockSize = 128;rijalg.KeySize = 256;rijalg.Padding = PaddingMode.None;rijalg.Mode = CipherMode.CBC;rijalg.Key = aesKey;rijalg.IV = iv;ICryptoTransform encryptor = rijalg.CreateEncryptor(rijalg.Key, rijalg.IV);return encryptor.TransformFinalBlock(bytes, 0, bytes.Length);}
  • iv是长度为16的字节数组,里边都是默认值0。

  • aeskey是一个长度为32的字节数组,不过计算的时候准备的是长度为40的字节数组,需要截一下。

  • Padding需要设置为PaddingMode.None,默认的不是这个。

其它就没什么好说的了。

为了不那么单调,来一张RDManger的使用界面:

C#怎么生成putty格式的ppk文件

到此,相信大家对“C#怎么生成putty格式的ppk文件”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

C#怎么生成putty格式的ppk文件

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

C#怎么生成putty格式的ppk文件

本篇内容主要讲解“C#怎么生成putty格式的ppk文件”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C#怎么生成putty格式的ppk文件”吧!背景2022国家级护网行动即将开启,根据阿里云给
2023-07-02

怎么用C#生成DataMatrix格式的二维码

这篇文章主要讲解了“怎么用C#生成DataMatrix格式的二维码”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么用C#生成DataMatrix格式的二维码”吧!1、附件为dll2、利用上
2023-06-25

怎么将文件PDF格式转换成Word格式

这篇文章给大家分享的是有关怎么将文件PDF格式转换成Word格式的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。(1)打开手机,在手机上的应用市场上搜索“PDF转换大师”,找到可以转换文档格式的工具,将其下载到手机
2023-06-05

Python怎么将csv格式转换成JSON格式文件

这篇文章主要介绍“Python怎么将csv格式转换成JSON格式文件”,在日常操作中,相信很多人在Python怎么将csv格式转换成JSON格式文件问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python怎
2023-06-02

windows怎么压缩文件成zip格式

这篇文章主要讲解了“windows怎么压缩文件成zip格式”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“windows怎么压缩文件成zip格式”吧!压缩文件成zip格式的方法:1、首先右键点
2023-07-02

Visual 中怎么利用C#生成DLL文件

本篇文章给大家分享的是有关Visual 中怎么利用C#生成DLL文件,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Visual C#生成DLL文件——预备知识DLL(Dynam
2023-06-17

怎么用PHP将文件转成JPG格式

今天小编给大家分享一下怎么用PHP将文件转成JPG格式的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。一、安装GD库要使用PH
2023-07-05

windows中ofd文件怎么转换成wps格式

本篇内容介绍了“windows中ofd文件怎么转换成wps格式”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!ofd文件转换成wps格式的方法
2023-01-03

windows中ofd文件怎么转换成pdf格式

这篇“windows中ofd文件怎么转换成pdf格式”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“windows中ofd文件
2023-07-02

云服务器怎么做成网盘文件格式的

要将云服务器上的文件以网盘文件的格式存储在云服务器上,首先需要在云服务器上安装相应的文件上传工具,然后在云服务器的配置文件中设置上传文件的格式,接着将上传到云服务器的文件以网盘文件的格式保存在服务器上的指定位置。要将云服务器上的文件以HTTP、SOAP、JSON等格式上传到云服务器的指定位置,可以使用相应的HTTP、SOAP、JSON等客户端库,通过相应的客户端库可以将文件以HTTP、SOAP、J...
2023-10-27

云服务器怎么做成网盘文件的格式

云服务器的使用可以使用户轻松地存储、共享和访问大量的文档、音频和视频。与传统的本地存储不同,云服务器具有许多优点,包括高可靠性、高可扩展性和高可用性。首先,云服务器可以提供高可靠性。用户可以将文件存储在云服务器上,以确保它们能够在任何时间和任何地点访问。当服务器出现故障时,它们可以自动重新分布和同步,以确保数据的一致性
云服务器怎么做成网盘文件的格式
2023-10-28

PHP中怎么将数据转换成json格式的文件

本篇内容主要讲解“PHP中怎么将数据转换成json格式的文件”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“PHP中怎么将数据转换成json格式的文件”吧!首先,让我们来了解一下什么是json格式
2023-07-05

怎么一键完成照片转PDF文件格式

这篇文章主要介绍了怎么一键完成照片转PDF文件格式,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1:首先我们熟悉一下这个软件的功能,比如他可以进行PDF转Word、PDF转P
2023-06-05

c语言中源文件编译后生成的文件是什么

这篇文章主要介绍“c语言中源文件编译后生成的文件是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“c语言中源文件编译后生成的文件是什么”文章能帮助大家解决问题。c语言编译后生成“.OBJ”的二进制
2023-07-04

C++静态库与动态库文件怎么生成和使用

这篇文章主要介绍“C++静态库与动态库文件怎么生成和使用”,在日常操作中,相信很多人在C++静态库与动态库文件怎么生成和使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C++静态库与动态库文件怎么生成和使用
2023-07-05

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录