Kleopatraがインストール済みなのに、GNOME Files(Nautilus)で.gpgをダブルクリックしても復号できない。
この場合は、既定アプリの指定に加えて、起動方法を定義する.desktopファイルを確認する。
対応MIME型とファイル引数の指定が欠けていれば、ユーザー用の.desktopで補うことで、復号と署名確認へファイルを渡せるようになる。
右クリックから暗号化や署名を始めるには、NautilusのPython拡張でOpenPGPサブメニューを追加する。
WindowsのGpg4win / GpgEXのように、ファイルを選んだ場所からKleopatraの操作画面を開ける構成になる。
対象環境と事前確認
対象はUbuntu 24.04 LTSのGNOMEデスクトップで、Kleopatraがインストール済みの環境である。 暗号化や署名には、普段使っているGnuPG環境の鍵を利用する。
以下の構成で、ダブルクリックからの復号と署名確認、Python拡張からの暗号化、署名、暗号化と署名の実行を確認済みである。
OS: Ubuntu 24.04.4 LTS (Noble Numbat)
ファイルマネージャー: GNOME Files / Nautilus(46系)
暗号操作のGUI: Kleopatra
拡張API: Nautilus 4.0(python3-nautilus)
まず、端末でKleopatraが見つかることと、利用できるオプションを確認する。
command -vで実行ファイルのパスが、--helpで操作の一覧が表示されれば、関連付けの確認へ進める。
command -v kleopatra
kleopatra --help
nautilus --version
dpkg-query -W kleopatra nautilus
command -vで何も表示されない場合は、Kleopatraのインストール先とPATHを確認する。
パッケージのバージョンは、最後のdpkg-queryで確認できる。
既定アプリなのにファイルを開けない理由
ファイルをダブルクリックしたとき、デスクトップはファイルの種類を表すMIME型と、その型の既定アプリを使って起動先を選ぶ。
アプリ側の.desktopには、処理できる型を示すMimeType=と、起動コマンドを示すExec=がある。
既定アプリの指定だけでは、起動コマンドへファイルを渡す方法までは補えない。
次のコマンドで、Kleopatraの.desktopファイルと、暗号化ファイルおよび署名ファイルの関連付けを確認する。
ls /usr/share/applications/ | grep -i kleopatra
xdg-mime query default application/pgp-encrypted
gio mime application/pgp-encrypted
gio mime application/pgp-signature
問題が起きた環境では、次のように表示された。
kleopatra_import.desktop
org.kde.kleopatra.desktop
org.kde.kleopatra.desktop
“application/pgp-encrypted” のデフォルトのアプリケーション: org.kde.kleopatra.desktop
登録されているアプリケーションはありません
推奨されているアプリケーションはありません
“application/pgp-signature” のデフォルトのアプリケーション: org.kde.kleopatra.desktop
登録されているアプリケーションはありません
推奨されているアプリケーションはありません
この出力では、既定アプリはorg.kde.kleopatra.desktopだが、登録アプリの一覧が空になっている。
続いて、その.desktopに対応MIME型とファイル引数の指定があるかを調べる。
grep -E '^(Name|Exec|MimeType|NoDisplay|Hidden)=' \
/usr/share/applications/org.kde.kleopatra.desktop
設定が不足している場合の出力例は次のとおり。
Exec=kleopatra
Name=Kleopatra
Exec=kleopatraには、選択したファイルを引数として渡す指定がない。
複数のファイルを渡すには%Fを使うと、それぞれのパスが独立した引数になる。
この出力なら、MimeType=の追加とExec=の変更が必要になる。
対応MIME型と既定アプリの優先順位は別の設定である。
それぞれの役割と%Fの意味は、freedesktop.orgの対応MIME型の仕様
とExecの仕様
で確認できる。
すでに両方のMIME型とファイル引数が設定されているなら、これらを補う作業は省略できる。
xdg-mime query filetypeで対象ファイルのMIME型を調べ、既定アプリの設定と一致するかを確認する。
ユーザー用の関連付けを設定する
/usr/share/applications/のファイルはパッケージ管理下にあり、更新で上書きされる可能性がある。
同じ名前のファイルを~/.local/share/applications/へ置き、自分のユーザーだけで上書きする。
パッケージ更新後もユーザー側のコピーが優先されるため、更新を機に動かなくなった場合は、配布版の.desktopと差分を確認する。
後で設定を戻せるよう、変更前の関連付けと既存のユーザー用ファイルを保存してから編集する。
以下は初回設定時に実行するコマンドである。
設定をやり直す場合はバックアップを上書きせず、末尾のvimコマンドから再開する。
mkdir -p ~/.local/share/nautilus-openpgp-backup
mkdir -p ~/.local/share/applications
xdg-mime query default application/pgp-encrypted \
> ~/.local/share/nautilus-openpgp-backup/pgp-encrypted.default
xdg-mime query default application/pgp-signature \
> ~/.local/share/nautilus-openpgp-backup/pgp-signature.default
if [ -f ~/.local/share/applications/org.kde.kleopatra.desktop ]; then
cp -p ~/.local/share/applications/org.kde.kleopatra.desktop \
~/.local/share/nautilus-openpgp-backup/org.kde.kleopatra.desktop
fi
cp /usr/share/applications/org.kde.kleopatra.desktop \
~/.local/share/applications/org.kde.kleopatra.desktop
vim ~/.local/share/applications/org.kde.kleopatra.desktop
[Desktop Entry]内のExec=を次の値に変更し、MimeType=を追加する。
下の3行は変更箇所の抜粋で、既存のType=、Name=、Icon=、Categories=などはそのまま残す。
MimeType=がすでにある場合は、既存の型を残して必要な型を追記する。
[Desktop Entry]
Exec=kleopatra --decrypt-verify %F
MimeType=application/pgp-encrypted;application/pgp-signature;
--decrypt-verifyは、渡したファイルの復号または署名確認を行うKleopatraのオプションである。
暗号化ファイルと署名ファイルを同じ起動コマンドで扱える。
オプションの一覧はKleopatraの公式マニュアル
にあるが、対象環境で利用できる指定はkleopatra --helpでも確認する。
アプリのMIME対応表を更新し、既定アプリを設定する。
update-desktop-databaseがない場合は、先にsudo apt install desktop-file-utilsで導入する。
update-desktop-database ~/.local/share/applications
xdg-mime default org.kde.kleopatra.desktop application/pgp-encrypted
xdg-mime default org.kde.kleopatra.desktop application/pgp-signature
gio mime application/pgp-encrypted
gio mime application/pgp-signature
nautilus -q
nautilus -qで開いているFilesのウィンドウが閉じるので、改めてFilesを起動する。
.gpgをダブルクリックし、Kleopatraの復号と署名確認の画面が開くことを確かめる。
画面が開かない場合は、対象ファイルがどのMIME型として認識されているかを調べる。
次の./document.gpgを、開けないファイルのパスに置き換える。
xdg-mime query filetype ./document.gpg
gio info -a standard::content-type ./document.gpg
表示されたMIME型がapplication/pgp-encryptedなら、上で設定した関連付けの対象になる。
別の型なら、その型の既定アプリをgio mimeで確認する。
.ascには鍵や署名も入るため、一律に復号へ関連付けず、右クリックの拡張で内容に応じた操作を選ぶ。
OpenPGPサブメニューの設計
ダブルクリックで復号できても、通常のPDFやテキストには暗号化を始める操作が必要になる。
Python拡張でOpenPGPメニューを追加すれば、選んだファイルに応じて暗号化、復号、署名確認、鍵のインポートを表示できる。

Nautilusへ右クリック項目を提供するのが、Nautilus.MenuProviderである。
python3-nautilusを使うと、選択されたファイルの一覧をPythonで受け取り、Nautilus.MenuItemを返せる。
拡張はファイルを分類して操作候補を表示し、選んだ操作とファイルをKleopatraへ渡す。 暗号処理と鍵管理はKleopatra / GnuPGに任せ、パスフレーズやPINの入力も既存の仕組みを使う。
スマートカードやYubiKeyを使う場合も、Kleopatraから利用できるよう設定済みなら、拡張側にカード操作を実装する必要はない。
| 選択したファイル | 判定 | 表示する操作 |
|---|---|---|
.txt、.pdfなど |
通常ファイル | 暗号化、署名、暗号化して署名 |
.gpg、.pgp |
拡張子で分類 | 復号 / 署名を確認 |
.sig |
分離署名として分類 | 署名を確認 |
.asc |
BEGIN PGP MESSAGE |
復号 / 署名を確認 |
.asc |
BEGIN PGP SIGNATURE |
署名を確認 |
.asc |
BEGIN PGP SIGNED MESSAGE |
署名を確認 |
.ascの公開鍵 |
BEGIN PGP PUBLIC KEY BLOCK |
公開鍵をインポート |
.ascの秘密鍵 |
BEGIN PGP PRIVATE KEY BLOCK |
秘密鍵をインポート |
判別できない.asc |
既知のヘッダーなし、または読み込み失敗 | 復号 / 署名を確認 |
| 元ファイルと分離署名 | .sigまたは署名の.ascを一緒に選択 |
署名を確認 |
同じ.ascでも、公開鍵と署名では必要な操作が違う。
たとえば-----BEGIN PGP PUBLIC KEY BLOCK-----で始まるファイルなら、公開鍵のインポートを表示する。
この開始行は、OpenPGPデータをテキストで表現するASCII Armorのヘッダーである。
拡張は先頭を最大64 KiB読み、ヘッダーから操作候補を選ぶ。
実際のデータの読み取りや署名の検証はKleopatraに任せる。
PGP MESSAGEも暗号化の有無をヘッダーだけでは断定できないため、復号と検証を兼ねる操作へ渡す。
複数選択は100件までとし、ディレクトリやfile:以外のURIが含まれる場合はメニューを出さない。
分類が混在した場合は、通常ファイルと分離署名を含む選択を検証へ、それ以外の未対応の組み合わせを復号と検証へ渡す。 鍵をインポートするときは、公開鍵だけ、または秘密鍵だけを選ぶと、それぞれのインポート項目が表示される。
Python拡張のインストール
拡張の読み込みにpython3-nautilus、起動失敗時の通知にlibnotify-binを使う。
システムのPythonから読み込まれるため、仮想環境へのpip installではなくAPTで導入する。
sudo apt install python3-nautilus libnotify-bin
mkdir -p ~/.local/share/nautilus-python/extensions
vim ~/.local/share/nautilus-python/extensions/openpgp.py
次のコード全体をopenpgp.pyに保存する。
NautilusがPythonモジュールとして読み込むため、実行権限の付与は不要である。
#!/usr/bin/env python3
"""OpenPGP integration for Nautilus API 4.0 using Kleopatra."""
from __future__ import annotations
import logging
import shutil
import subprocess
from enum import Enum, auto
from pathlib import Path
from typing import Sequence
from urllib.parse import unquote, urlparse
import gi
gi.require_version("Nautilus", "4.0")
from gi.repository import GObject, Nautilus
APP_NAME = "Nautilus OpenPGP"
LOG_DIR = Path.home() / ".cache"
LOG_FILE = LOG_DIR / "nautilus-openpgp.log"
ARMOR_READ_LIMIT = 64 * 1024
MAX_SELECTION = 100
ENCRYPTED_SUFFIXES = {".gpg", ".pgp"}
SIGNATURE_SUFFIXES = {".sig"}
ASCII_ARMOR_SUFFIXES = {".asc"}
try:
LOG_DIR.mkdir(parents=True, exist_ok=True)
logging.basicConfig(
filename=LOG_FILE,
level=logging.INFO,
format="%(asctime)s %(levelname)s %(name)s: %(message)s",
)
except OSError:
logging.basicConfig(level=logging.WARNING)
logger = logging.getLogger("nautilus-openpgp")
class FileKind(Enum):
NORMAL = auto()
ENCRYPTED = auto()
DETACHED_SIGNATURE = auto()
ASCII_ENCRYPTED = auto()
ASCII_SIGNATURE = auto()
ASCII_SIGNED_MESSAGE = auto()
PUBLIC_KEY = auto()
PRIVATE_KEY = auto()
UNKNOWN_ASCII = auto()
ASCII_HEADERS: tuple[tuple[bytes, FileKind], ...] = (
(b"-----BEGIN PGP MESSAGE-----", FileKind.ASCII_ENCRYPTED),
(b"-----BEGIN PGP SIGNED MESSAGE-----", FileKind.ASCII_SIGNED_MESSAGE),
(b"-----BEGIN PGP SIGNATURE-----", FileKind.ASCII_SIGNATURE),
(b"-----BEGIN PGP PUBLIC KEY BLOCK-----", FileKind.PUBLIC_KEY),
(b"-----BEGIN PGP PRIVATE KEY BLOCK-----", FileKind.PRIVATE_KEY),
)
class OpenPGPMenuProvider(GObject.GObject, Nautilus.MenuProvider):
"""KleopatraをNautilusのコンテキストメニューへ統合する。"""
def __init__(self) -> None:
super().__init__()
self.kleopatra = shutil.which("kleopatra")
self.notify_send = shutil.which("notify-send")
if self.kleopatra:
logger.info("Kleopatra detected: %s", self.kleopatra)
else:
logger.error("Kleopatra was not found in PATH")
def _notify(self, title: str, message: str) -> None:
logger.warning("%s: %s", title, message)
if not self.notify_send:
return
try:
subprocess.Popen(
[self.notify_send, "--app-name", APP_NAME, title, message],
start_new_session=True,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
except OSError:
logger.exception("Failed to launch notify-send")
@staticmethod
def _file_info_to_path(file_info: Nautilus.FileInfo) -> Path | None:
try:
if file_info.get_uri_scheme() != "file":
return None
if file_info.is_directory():
return None
parsed = urlparse(file_info.get_uri())
if parsed.scheme != "file" or not parsed.path:
return None
return Path(unquote(parsed.path))
except Exception:
logger.exception("Failed to convert FileInfo to Path")
return None
def _get_local_paths(
self, files: Sequence[Nautilus.FileInfo]
) -> list[Path]:
paths: list[Path] = []
for file_info in files:
path = self._file_info_to_path(file_info)
if path is not None:
paths.append(path)
return paths
@staticmethod
def _inspect_ascii_armor(path: Path) -> FileKind | None:
try:
with path.open("rb") as file:
data = file.read(ARMOR_READ_LIMIT)
except OSError:
logger.exception(
"Could not read file for ASCII Armor detection: %s", path
)
return None
stripped = data.lstrip(b"\xef\xbb\xbf\r\n\t ")
for header, kind in ASCII_HEADERS:
if stripped.startswith(header):
return kind
return None
def _classify_file(self, path: Path) -> FileKind:
suffix = path.suffix.lower()
if suffix in ASCII_ARMOR_SUFFIXES:
armor_kind = self._inspect_ascii_armor(path)
return armor_kind if armor_kind is not None else FileKind.UNKNOWN_ASCII
if suffix in SIGNATURE_SUFFIXES:
return FileKind.DETACHED_SIGNATURE
if suffix in ENCRYPTED_SUFFIXES:
return FileKind.ENCRYPTED
return FileKind.NORMAL
def _run_kleopatra_paths(
self, operation: str, paths: Sequence[Path]
) -> None:
if not self.kleopatra:
self._notify("OpenPGP", "Kleopatraが見つかりません。")
return
if not paths:
return
command = [
self.kleopatra, "--openpgp", operation,
*[str(path) for path in paths],
]
logger.info("Executing: %r", command)
try:
subprocess.Popen(
command,
start_new_session=True,
stdin=subprocess.DEVNULL,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
close_fds=True,
)
except OSError as exc:
logger.exception("Failed to launch Kleopatra")
self._notify("OpenPGP", f"Kleopatraの起動に失敗しました: {exc}")
def _run_operation(
self,
_menu_item: Nautilus.MenuItem,
operation: str,
files: Sequence[Nautilus.FileInfo],
) -> None:
self._run_kleopatra_paths(operation, self._get_local_paths(files))
@staticmethod
def _new_item(*, name: str, label: str, tip: str) -> Nautilus.MenuItem:
return Nautilus.MenuItem(
name=f"OpenPGP::{name}", label=label, tip=tip
)
def _append_operation(
self,
submenu: Nautilus.Menu,
files: Sequence[Nautilus.FileInfo],
*,
name: str,
label: str,
tip: str,
operation: str,
) -> None:
item = self._new_item(name=name, label=label, tip=tip)
item.connect("activate", self._run_operation, operation, files)
submenu.append_item(item)
def _build_normal_menu(
self, submenu: Nautilus.Menu, files: Sequence[Nautilus.FileInfo]
) -> None:
self._append_operation(
submenu, files, name="Encrypt", label="暗号化…",
tip="選択したファイルをOpenPGPで暗号化します",
operation="--encrypt",
)
self._append_operation(
submenu, files, name="Sign", label="署名…",
tip="選択したファイルにOpenPGP署名を作成します",
operation="--sign",
)
self._append_operation(
submenu, files, name="EncryptSign", label="暗号化して署名…",
tip="選択したファイルを暗号化して署名します",
operation="--encrypt-sign",
)
def _build_decrypt_menu(
self, submenu: Nautilus.Menu, files: Sequence[Nautilus.FileInfo]
) -> None:
self._append_operation(
submenu, files, name="DecryptVerify", label="復号 / 署名を確認…",
tip="暗号化されたファイルを復号し、署名があれば確認します",
operation="--decrypt-verify",
)
def _build_verify_menu(
self, submenu: Nautilus.Menu, files: Sequence[Nautilus.FileInfo]
) -> None:
self._append_operation(
submenu, files, name="Verify", label="署名を確認…",
tip="OpenPGP署名を確認します", operation="--verify",
)
def _build_import_menu(
self,
submenu: Nautilus.Menu,
files: Sequence[Nautilus.FileInfo],
*,
secret: bool,
) -> None:
self._append_operation(
submenu, files,
name="ImportPrivateKey" if secret else "ImportPublicKey",
label="秘密鍵をインポート…" if secret else "公開鍵をインポート…",
tip=(
"選択したOpenPGP秘密鍵をKleopatraにインポートします"
if secret
else "選択したOpenPGP公開鍵をKleopatraにインポートします"
),
operation="--import-certificate",
)
def get_file_items(
self, files: Sequence[Nautilus.FileInfo]
) -> list[Nautilus.MenuItem]:
if not files or not self.kleopatra or len(files) > MAX_SELECTION:
return []
paths = self._get_local_paths(files)
if len(paths) != len(files):
return []
kinds = {self._classify_file(path) for path in paths}
root_item = self._new_item(
name="Root", label="OpenPGP",
tip="OpenPGPの暗号化、署名、復号、検証",
)
submenu = Nautilus.Menu()
if kinds == {FileKind.NORMAL}:
self._build_normal_menu(submenu, files)
elif kinds <= {FileKind.ENCRYPTED, FileKind.ASCII_ENCRYPTED}:
self._build_decrypt_menu(submenu, files)
elif kinds <= {
FileKind.DETACHED_SIGNATURE,
FileKind.ASCII_SIGNATURE,
FileKind.ASCII_SIGNED_MESSAGE,
}:
self._build_verify_menu(submenu, files)
elif kinds == {FileKind.PUBLIC_KEY}:
self._build_import_menu(submenu, files, secret=False)
elif kinds == {FileKind.PRIVATE_KEY}:
self._build_import_menu(submenu, files, secret=True)
elif kinds == {FileKind.UNKNOWN_ASCII}:
self._build_decrypt_menu(submenu, files)
elif FileKind.NORMAL in kinds and (
FileKind.DETACHED_SIGNATURE in kinds
or FileKind.ASCII_SIGNATURE in kinds
):
self._build_verify_menu(submenu, files)
else:
self._build_decrypt_menu(submenu, files)
root_item.set_submenu(submenu)
return [root_item]
def get_background_items(
self, current_folder: Nautilus.FileInfo
) -> list[Nautilus.MenuItem]:
return []
対象には、ローカルに保存したテキストやPDFなどの通常ファイルを選ぶ。
.ascは右クリック時に先頭を読み込むため、応答の遅いマウント先ではメニュー表示も待たされることがある。
FIFO(名前付きパイプ)などの特殊ファイルは自動で除外されず、読み込みで待ち続けるおそれがあるので対象にしない。
Kleopatraの起動には、シェルを介さず引数のリストをsubprocess.Popenへ渡す。
そのためファイル名に空白があっても分割されず、シェルの記号としても解釈されない。
拡張を有効にして動作を確認する
保存後に構文を確認し、Nautilusを終了して起動し直す。
Ubuntu標準のPythonで確認するため、ここでは/usr/bin/python3を指定する。
/usr/bin/python3 -m py_compile \
~/.local/share/nautilus-python/extensions/openpgp.py
nautilus -q
構文エラーが出なければ、Filesを開いてテスト用のテキストファイルを選ぶ。 自分で復号できるよう、暗号化の宛先には自分の公開鍵を含め、対応する秘密鍵を利用できる状態にしておく。
通常ファイルのsample.txtでは、OpenPGPを開くと「暗号化…」「署名…」「暗号化して署名…」が並ぶ。

暗号化したsample.txt.gpgを選ぶと、メニューは「復号 / 署名を確認…」に切り替わる。

メニューが表示されることに加え、復号後の内容と署名の検証結果まで確かめる。
- 通常ファイルの右クリックに
OpenPGPが現れ、暗号化、署名、暗号化して署名を選べることを確認する。 - 暗号化した
.gpgをダブルクリックし、Kleopatraで復号して元の内容に戻ることを確認する。 - 署名を作成し、署名ファイルから検証してKleopatraの結果を確認する。
- 暗号化して署名したファイルを復号し、署名の検証結果も確認する。
- 空白を含む名前や複数選択でも、意図したファイルがKleopatraへ渡ることを確認する。
分離署名の検証には元ファイルも必要になる。
たとえばdocument.pdfとdocument.pdf.sigを同じフォルダーに置き、2つを選んで「署名を確認…」を実行する。
元ファイルの指定を求められたら、署名の対象になったdocument.pdfを選ぶ。
.ascでは、公開鍵、秘密鍵、署名、署名付きテキストごとに、表のメニューが出ることも確認する。
鍵を取り込む必要がなければ、表示の確認だけでよい。
署名を信頼してよいか判断する際は、検証結果に加え、公開鍵のフィンガープリントが署名者から確認した値と一致するかを確かめる。
ログと起動しない場合の切り分け
拡張のログは次のコマンドで確認する。
tail -f ~/.cache/nautilus-openpgp.log
Kleopatraの検出結果、起動コマンド、読み込みや起動に失敗した際の例外を記録する。
起動コマンドには選択したファイルの絶対パスが含まれるため、ログを共有する際はファイル名も確認する。 ログは自動で世代交代せず追記されるため、大きくなったら不要な記録を削除する。
| 症状 | 確認する箇所 |
|---|---|
OpenPGPが出ない |
配置先、Pythonの構文、Nautilusの再起動、python3-nautilusの導入 |
| 一部の選択で出ない | ディレクトリ、file:以外のURI、101件以上の選択がないか |
| Kleopatra未検出のログが出る | Nautilusから見えるPATHにkleopatraがあるか |
| メニューから起動できない | ログのFailed to launch Kleopatraとデスクトップ通知 |
| 起動するが処理できない | Kleopatraの画面、対象ファイル、必要な鍵、検証時の元ファイル |
| ログファイルが作られない | キャッシュへの書き込み権限、拡張の読み込みエラー |
メニューが出ず通知もない場合は、ログにKleopatra was not found in PATHがないかを確認する。
Kleopatraが見つからないと、拡張はメニューを表示しない。
メニューを選んだ後にプロセスを起動できなかった場合は、ログに加えてデスクトップ通知にもエラーが出る。
Kleopatraが開いた後のエラーは、Kleopatraの画面で確認する。 拡張のログにはKleopatraの標準出力と標準エラーが残らないため、詳しい出力が必要なら端末から同じ操作を試す。
kleopatra --openpgp --decrypt-verify ./document.gpg
ログファイル自体が作られない場合は、Nautilusを終了して端末から起動し、拡張の読み込みエラーが出ていないかを確認する。 別の拡張によるログ設定が優先され、指定したファイルへ記録されない場合もある。
nautilus -q
nautilus
アンインストールと関連付けの復元
右クリック拡張だけを外す場合は、openpgp.pyを削除してNautilusを起動し直す。
この操作でKleopatraやGnuPGの鍵は削除されない。
rm -i -- ~/.local/share/nautilus-python/extensions/openpgp.py
nautilus -q
ダブルクリックの設定も戻す場合は、ユーザー用の.desktopを元に戻す。
設定前のコピーがある場合は復元し、もともとなかった場合は今回のコピーを削除する。
if [ -f ~/.local/share/nautilus-openpgp-backup/org.kde.kleopatra.desktop ]; then
cp -p ~/.local/share/nautilus-openpgp-backup/org.kde.kleopatra.desktop \
~/.local/share/applications/org.kde.kleopatra.desktop
else
rm -i -- ~/.local/share/applications/org.kde.kleopatra.desktop
fi
update-desktop-database ~/.local/share/applications
既定アプリも、設定前に記録した値へ戻す。 以下は保存値がある型だけを復元する。
for pgp_type in pgp-encrypted pgp-signature; do
previous_app=$(cat "$HOME/.local/share/nautilus-openpgp-backup/$pgp_type.default")
if [ -n "$previous_app" ]; then
xdg-mime default "$previous_app" "application/$pgp_type"
fi
done
nautilus -q
バックアップした.defaultファイルが空の場合は、追加した関連付けを手動で外す。
保存値がないため、上のコマンドでは復元できない。
~/.config/mimeapps.listなど、設定時に変更されたユーザー用のmimeapps.listを開く。
application/pgp-encryptedとapplication/pgp-signatureから追加した指定だけを外し、他の型や同じ行にある別アプリの指定は残す。
ログが不要なら、次のファイルも削除できる。
python3-nautilusとlibnotify-binは他の拡張からも利用されるため、そのまま残してよい。
rm -i -- ~/.cache/nautilus-openpgp.log
Filesから普段の鍵を使う
設定後は、暗号化済みのファイルをダブルクリックして復号し、通常ファイルは右クリックのOpenPGPから暗号化や署名を選べる。
公開鍵の.ascなら、同じメニューからインポートを始められる。
宛先や署名鍵の選択、処理結果の確認にはKleopatraを使う。 普段の鍵管理を保ったまま、Filesで選んだファイルに対してOpenPGPの操作を始められる。
補足:Python拡張の前に試したNautilus Scripts
Python拡張を作る前に、Nautilus Scriptsで選択したファイルをKleopatraへ渡せるかを試した。 短いシェルスクリプトだけで、暗号化、署名、暗号化と署名が動くことを確認できた。
この検証で、暗号操作の画面はKleopatraに任せ、Nautilus側ではファイルを渡せばよいと分かった。
試したのは以下の3本である。 呼び出しだけを切り分けて試す際にも使えるが、Python拡張の導入にこれらの作成は必要ない。
mkdir -p ~/.local/share/nautilus/scripts
cat > ~/.local/share/nautilus/scripts/暗号化 <<'EOF'
#!/usr/bin/env bash
kleopatra --openpgp --encrypt "$@"
EOF
cat > ~/.local/share/nautilus/scripts/署名 <<'EOF'
#!/usr/bin/env bash
kleopatra --openpgp --sign "$@"
EOF
cat > ~/.local/share/nautilus/scripts/暗号化+署名 <<'EOF'
#!/usr/bin/env bash
kleopatra --openpgp --encrypt-sign "$@"
EOF
chmod +x \
~/.local/share/nautilus/scripts/暗号化 \
~/.local/share/nautilus/scripts/署名 \
~/.local/share/nautilus/scripts/暗号化+署名
nautilus -q
Filesでファイルを選ぶと、右クリックの「スクリプト」以下に3つの操作が現れる。
"$@"を使うことで、空白を含むファイル名も引数の区切りを保って渡せる。
各項目を選び、Kleopatraで宛先や署名鍵を選択する画面が開けば、ファイルを渡せている。
ただ、この3本では暗号化済みのファイルを選んでも、メニューは暗号化と署名のままである。
選んだファイルに合わせて復号や鍵のインポートを表示するため、専用のOpenPGPメニューを作れるPython拡張へ移行した。
試したScripts版の片付け
この補足のScripts版を試した場合は、Python拡張への移行後に3ファイルを削除できる。 同名の別スクリプトを使っている場合は削除対象に含めない。
ls -l \
~/.local/share/nautilus/scripts/暗号化 \
~/.local/share/nautilus/scripts/署名 \
~/.local/share/nautilus/scripts/暗号化+署名
rm -i -- \
~/.local/share/nautilus/scripts/暗号化 \
~/.local/share/nautilus/scripts/署名 \
~/.local/share/nautilus/scripts/暗号化+署名
nautilus -q