Linux Bash脚本自动创建keystore和生成公钥方式

 更新时间:2025年11月11日 09:23:45   作者:fengyehongWorld  
该文章介绍了如何使用Bash脚本自动化生成新的keystore文件并提取公钥的过程,脚本通过获取脚本绝对路径、使用关联数组和函数传递数组参数等方法来实现自动化,并且可以在Windows上使用Git Bash运行

一、需求

现场有一个项目中使用了keystore证明书,现要求每年都需要生成一个新的keystore文件,并且根据keystore文件中的私钥生成公钥,然后将公钥提供给其他项目使用。

  • 生成keystore文件的命令很长,手动通过命令行输入不仅繁琐,而且很容易出错,因此要求写一个脚本实现
  • 要求使用Bash脚本书写,书写完毕之后,如果在windows上安装了Git for Bash的话,还可以在直接在windows上执行。

二、脚本实现

#!/usr/bin/env bash

# 判断keytool命令是否被安装
if ! command -v keytool >/dev/null 2>&1; then
    echo "【keytool】命令并没有被安装, 请确认!"
    exit 1
fi

# 判断openssl命令是否被安装
if ! command -v openssl >/dev/null 2>&1; then
    echo "【openssl】命令并没有被安装, 请确认!"
    exit 1
fi

# 获取当前脚本的绝对路径
SCRIPT_PATH="$(readlink -f "${BASH_SOURCE[0]}")"
# 根据脚本的绝对路径获取脚本所在目录的绝对路径
SCRIPT_DIR="$(dirname "$SCRIPT_PATH")"

# 私钥别名
ALIAS='alias'
# 密码
PASSWD='nosecret'
# 不带后缀的文件名
FILE_NAME='test_mpl_ws_api'
# pem公钥所对应的key名称
PEM_PUBLIC_KEY='PEM_PUBLIC_KEY_PATH'
# 组织信息
DNAME_INFO='CN=KDDI, OU=IT, O=MyCompany, L=Tokyo, ST=Tokyo, C=JP'

# 创建一个关联数组, 关联数组中的key和value都可以使用变量
declare -A filePathMap=(
    # keystore文件的绝对路径
    [KEYSTORE_FILE_PATH]="$SCRIPT_DIR/${FILE_NAME}.keystore"
    # cer公钥文件的所在路径
    [CER_PUBLIC_KEY_PATH]="$SCRIPT_DIR/${FILE_NAME}.cer"
    # pem公钥文件的所在路径
    ["$PEM_PUBLIC_KEY"]="$SCRIPT_DIR/${FILE_NAME}.pem"
)

# 进入当前脚本所在的目录
pushd "$SCRIPT_DIR" >/dev/null || exit 1

# 生成一个keystore文件
keytool -genkeypair \
-alias "$ALIAS" \
-keyalg RSA \
-sigalg SHA384withRSA \
-keysize 2048 \
-validity 365 \
-keystore "${filePathMap['KEYSTORE_FILE_PATH']}" \
-dname "$DNAME_INFO" \
-storepass "$PASSWD" \
-keypass "$PASSWD"

# 根据keystore文件中的私钥生成cer格式的公钥
keytool -exportcert \
-alias "$ALIAS" \
-keystore "${filePathMap['KEYSTORE_FILE_PATH']}" \
-storepass "$PASSWD" \
-file "${filePathMap['CER_PUBLIC_KEY_PATH']}"

# 通过openssl命令将der格式的公钥转换为pem格式的公钥
openssl x509 \
-inform der \
-in "${filePathMap['CER_PUBLIC_KEY_PATH']}" \
-outform pem \
-out "${filePathMap["$PEM_PUBLIC_KEY"]}"

# 定义一个删除文件的函数
function cleanup_files() {

    local -n pathMap=$1

    # 遍历引入的map
    for pathKey in "${!pathMap[@]}"; do
        # local的局部变量只能在函数内部使用
        local file_path="${pathMap[$pathKey]}"
        # 如果文件存在的话, 就删除
        [[ -f "$file_path" ]] && rm -- "$file_path"
    done
}

# 删除生成的文件
sleep 5
# 调用自定义的函数, 传入关联数组, 删除文件
cleanup_files filePathMap

# 返回到原目录
popd >/dev/null

read -p "→ 脚本执行结束, 按任意键结束 . . . " -n1 -s

三、脚本重点语法解析

获取当前脚本绝对路径和脚本所在的文件夹

# 获取当前脚本的绝对路径
SCRIPT_PATH="$(readlink -f "${BASH_SOURCE[0]}")"
# 根据脚本的绝对路径获取脚本所在目录的绝对路径
SCRIPT_DIR="$(dirname "$SCRIPT_PATH")"

Bash中虽然没有Map,但是Bash中的关联数组的特性和map类似

declare -A filePathMap=(
    # keystore文件的绝对路径
    [KEYSTORE_FILE_PATH]="$SCRIPT_DIR/${FILE_NAME}.keystore"
    # cer公钥文件的所在路径
    [CER_PUBLIC_KEY_PATH]="$SCRIPT_DIR/${FILE_NAME}.cer"
    # pem公钥文件的所在路径
    ["$PEM_PUBLIC_KEY"]="$SCRIPT_DIR/${FILE_NAME}.pem"
)

调用函数,传递关联数组

  • Bash 没法直接传关联数组,但你可以把数组名传进去,用 declare -n(Bash 4.3+)引用,Bash 4.3之前的旧版本的Bash并不支持。
  • -n 表示 nameref 引用。函数内部用 local -n pathMap=$1,引用只是局部的别名,原数组本身在外部仍然存在,不会意外覆盖或污染全局变量。
  • 函数结束后,局部变量的pathMap作用域消失,不影响其他变量。
function cleanup_files() {

    local -n pathMap=$1

    # 遍历引入的map
    for pathKey in "${!pathMap[@]}"; do
        # local的局部变量只能在函数内部使用
        local file_path="${pathMap[$pathKey]}"
        # 如果文件存在的话, 就删除
        [[ -f "$file_path" ]] && rm -- "$file_path"
    done
}

# 调用自定义的函数, 传入关联数组, 删除文件
cleanup_files filePathMap

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Linux账号文件控制管理步骤详解

    Linux账号文件控制管理步骤详解

    在本篇文章里小编给大家整理了关于Linux账号文件控制管理的步骤和实例,需要的朋友们可以参考下。
    2019-08-08
  • linux利用CSF防火墙屏蔽恶意请求

    linux利用CSF防火墙屏蔽恶意请求

    本篇文章主要介绍了linux利用CSF防火墙屏蔽恶意请求,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-05-05
  • Apache设置目录禁止访问

    Apache设置目录禁止访问

    这篇文章主要介绍了如何在Apache中设置目录禁止访问,非常的简单实用,有需要的朋友可以参考下
    2014-11-11
  • Shell 数组与关联数组详解及实例代码

    Shell 数组与关联数组详解及实例代码

    这篇文章主要介绍了 Shell 数组与关联数组详解及实例代码的相关资料,需要的朋友可以参考下
    2017-01-01
  • linux ssh端口转发的三种方式

    linux ssh端口转发的三种方式

    这篇文章主要介绍了linux ssh端口转发的三种方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-10-10
  • 详解Linux文件中的数据是如何被写进磁盘

    详解Linux文件中的数据是如何被写进磁盘

    Linux 中,我们的每一个进程,打开的每一个文件都要有自己的 struct inode 对象和自己的文件页缓冲区(就是所谓的内核缓冲区),本文我们给大家介绍了Linux文件中的数据是如何被写进磁盘,需要的朋友可以参考下
    2024-05-05
  • centos 6.X升级ffmpeg包步骤详解

    centos 6.X升级ffmpeg包步骤详解

    众所周知FFmpeg是一个开源免费跨平台的视频和音频流方案,属于自由软件,采用LGPL或GPL许可证(依据你选择的组件)。之前公司已经安装了ffmpeg包,但因为时间较久,所以最近打算升级下,所以这篇文章就记录了在centos 6.X升级ffmpeg包的详细步骤,下面来一起看看吧。
    2016-11-11
  • 如何实现为Ubuntu扩容(添加新的硬盘空间)

    如何实现为Ubuntu扩容(添加新的硬盘空间)

    这篇文章主要介绍了如何实现为Ubuntu扩容(添加新的硬盘空间)问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • Linux CentOS6.6系统中安装mysql源码包的方法

    Linux CentOS6.6系统中安装mysql源码包的方法

    Linux系统中如何安装mysql的源码包呢?这里以CentOS6.6系统中安装MySQL的源码包,进行讲解。本文分步骤给大家介绍的非常详细,感兴趣的朋友一起看看吧
    2016-10-10
  • VMnet8模式虚拟机配置全过程

    VMnet8模式虚拟机配置全过程

    文章介绍了如何配置虚拟网关以实现不同网络之间的互连,包括前置知识网关的基本概念、虚拟机配置虚拟网关的步骤以及主机配置虚拟网关的方法
    2024-11-11

最新评论